diff --git a/CMakeLists.txt b/CMakeLists.txt index 77b5ca9..b775907 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ cmake_minimum_required (VERSION 3.5.0) -set (SDL_BGI_VERSION 2.5.0) +set (SDL_BGI_VERSION 2.6.0) # Project name project (SDL_bgi VERSION ${SDL_BGI_VERSION} LANGUAGES C) @@ -22,10 +22,10 @@ include_directories (SDL_bgi ${SDL2_INCLUDE_DIRS}) include (GNUInstallDirs) # fix stupid bug on Linux -string (STRIP ${SDL2_LIBRARIES} SDL2_LIBRARIES) +# string (STRIP ${SDL2_LIBRARIES} SDL2_LIBRARIES) # Find source files -file (GLOB SOURCES src/*.c) +file (GLOB SOURCES src/SDL_bgi.c) # Include header files include_directories (src) @@ -61,8 +61,7 @@ file (GLOB man doc/graphics.3.gz) install (FILES ${man} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3) # Install test programs -file (GLOB test test/*) -install (FILES ${test} DESTINATION ${CMAKE_INSTALL_DOCDIR}/test) +install (DIRECTORY test/ DESTINATION ${CMAKE_INSTALL_DOCDIR}/test) # --- Packaging, thanks to cpack diff --git a/ChangeLog b/ChangeLog index 91ba44e..00b2ebc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,34 @@ Changelog --------- +v. 2.6.0, 2022-05-30 + +- Emscripten support: unmodified SDL_bgi programs can be compiled to + WebAssembly embedded in html pages +- added test/Makefile.emscripten, test/emcc.sh, doc/emscripten.md, + doc/emscripten.pdf +- added support for "environment files" (Emscripten replacement for + environment variables) +- added getclick(), doubleclick() +- extended mouseclick() +- update Windows Makefiles to SDL2-2.0.22 + +v. 2.5.1, 2022-02-28 + +- fixed bug in getch() +- added copysurface(), lastkey() +- added test/loadimage.c (demo for SDL2_image and copysurface()); + added test/pdj.c (demo for lastkey()) +- modified build.sh to to run on GNU/Linux only; renamed as mkpkg.sh + to avoid confusion +- added support for the tcc compiler (GNU/Linux only); added + test/tccrun +- modified CMakeList.txt +- documentation: added doc/howto_AppImage.md, doc/howto_AppImage.pdf, + doc/README.md; minor updates +- added doc/icon.png +- update Windows Makefiles to SDL2-2.0.20 + v. 2.5.0, 2021-09-20 - fixed kbhit() bug on MSYS2 (at last!) - fixed minor bug in setallpalette() @@ -57,7 +85,7 @@ v. 2.4.1, 2020-08-08 - implemented a 16-colour palette that uses the same RGB values as Turbo C. This palette is used if the environment variable SDL_BGI_PALETTE is set to "BGI" -- extended 'setpalette()' to modify the default 16 colours too +- extended setpalette() to modify the default 16 colours too (requested by Austin Hurst) - added initpalette() to restore the original 16 colours in the palette diff --git a/INSTALL_Emscripten.md b/INSTALL_Emscripten.md new file mode 100644 index 0000000..917075d --- /dev/null +++ b/INSTALL_Emscripten.md @@ -0,0 +1,48 @@ +# `SDL_bgi` and Emscripten + +Unmodified `SDL_bgi` programs can be compiled to WebAssembly using the +[Emscripten](https://emscripten.org/) compiler `emcc`. The following +tools are used to produce standalone `html` files that can be run in +supported browsers: + +- `src/Makefile` provides a `wasm` target, only available when the +`EMSDK` environment variable is defined; +- `test/emcc.sh` can be used to compile a program; +- `test/Makefile.emcc` compiles the sample programs. + +Emscripten support was tested with `emcc` 3.1.8 and `clang'' 15.0.0 on +GNU/Linux Mint 20.2 and MSYS2 20220503. + + +## Installing Emscripten Support + +Emscripten must be properly installed, and the `EMSDK` environment +variable must be defined; please consult the Emscripten [Download and +install](https://emscripten.org/docs/getting_started/downloads.html) +page. + +To compile `SDL_bgi` and install Emscripten support: + +``` +$ cd src/ +src/$ make wasm +*** Building on Linux *** +... +src/$ make clean +``` + +Files will be installed in appropriate directories: + +```` +graphics.h -> $EMSDK/upstream/emscripten/cache/sysroot/include +SDL_bgi.h -> $EMSDK/upstream/emscripten/cache/sysroot/include/SDL2 +libSDL_bgi.a -> $EMSDK/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten +```` + +To uninstall: + +```` +$ cd src/ +src/$ make unwasm +```` + diff --git a/INSTALL_Linux.md b/INSTALL_Linux.md index 4e470b0..dcb72fb 100644 --- a/INSTALL_Linux.md +++ b/INSTALL_Linux.md @@ -1,7 +1,7 @@ -# Installing `SDL_bgi` in GNU/Linux +# Installing `SDL_bgi` on GNU/Linux The easiest way to install `SDL_bgi` is by using the binary packages -provided at in `.deb` and +provided at in `.deb` and `.rpm` format. Alternatively, you can easily compile `SDL_bgi` yourself, as shown below. @@ -19,7 +19,7 @@ you'll also need `make` and a C compiler; `gcc` or `clang` are fine. To compile and install `SDL_bgi`, run the following commands: - $ VERSION=2.5.0 + $ VERSION=2.5.1 $ tar zxvf SDL_bgi-$VERSION.tar.gz $ cd SDL_bgi-$VERSION/src $ make @@ -38,10 +38,10 @@ This only works if `cmake` and `cpack` are installed. To compile the `SDL_bgi` library and make `.deb` or `.rpm` packages: - $ VERSION=2.5.0 + $ VERSION=2.5.1 $ tar zxvf SDL_bgi-$VERSION.tar.gz $ cd SDL_bgi-$VERSION - $ ./build.sh + $ ./mkpkg.sh which creates a subdirectory called `build/`, moves to it, runs `cmake`, then `cpack`. In a few seconds, in directory `build/` you diff --git a/INSTALL_Windows.md b/INSTALL_Windows.md index 72cc9ce..7d41ded 100644 --- a/INSTALL_Windows.md +++ b/INSTALL_Windows.md @@ -1,21 +1,24 @@ -# Installing `SDL_bgi` in Windows +# Installing `SDL_bgi` on Windows The easiest way to install `SDL_bgi` is by using the binary packages -provided at , for MSYS2 + +provided at , for MSYS2 + mingw-w64, CodeBlocks, and Dev-C++. Alternatively, you can easily compile `SDL_bgi` yourself, as shown below. The following sections were tested with: -- msys2-x86_64-20200720.exe (**note:** previous releases may not work!) +- msys2-x86_64-20220128 - codeblocks-20.03mingw - Dev-Cpp 5.11 + TDM-GCC 4.9.2 +- SDL2-2.0.20 +**Please note:** previous MSYS2 releases may not work! -## Installing the MSYS2 + Mingw-w64 Binaries -Let's assume you installed SDL2 as native package, that is -`mingw-w64-x86_64-SDL2`. +## Installing the MSYS2 + MINGW64 Binaries + +Provided binaries were compiled on `msys2` and its native package +`mingw-w64-x86_64-SDL2` version 2.0.22-1. Start the MSYS2 shell, unzip the `SDL_bgi` archive, then copy: @@ -24,20 +27,21 @@ Start the MSYS2 shell, unzip the `SDL_bgi` archive, then copy: bin/Mingw64/SDL_bgi.dll -> /mingw64/bin Please note that to run a program compiled with `SDL_bgi` outside of -the MSYS2 environment (e.g. in an ordinary command prompt), you will need -to copy `SDL_bgi.dll` and `SDL2.dll` to the same directory as the program. +the MSYS2 environment (e.g. in an ordinary Windows command prompt), +you will need to copy `SDL_bgi.dll` and `SDL2.dll` to the same +directory as the program. ## Installing the Code::Blocks Binaries Let's assume that you installed CodeBlocks in `C:\CodeBlocks` and SDL2 -development libraries in in `C:\SDL2-2.0.16`. Change the following +development libraries in in `C:\SDL2-2.0.22`. Change the following instructions as needed for your installation. Unzip `SDL_bgi` archive, then copy: src/graphics.h -> C:\CodeBlocks\MinGW\include - src/SDL_bgi.h -> C:\SDL2-2.0.16\i686-w64-mingw32\include\SDL2 + src/SDL_bgi.h -> C:\SDL2-2.0.22\i686-w64-mingw32\include\SDL2 bin/CodeBlocks/SDL_bgi.dll -> C:\CodeBlocks\MinGW\bin To learn how to compile programs, please see `howto_CodeBlocks.md`. @@ -46,13 +50,13 @@ To learn how to compile programs, please see `howto_CodeBlocks.md`. ## Installing the Dev-C++ Binaries Let's assume that you installed Dev-C++ in `C:\DevCpp` and SDL2 -in `C:\SDL2-2.0.16`. Change the following instructions as needed for +in `C:\SDL2-2.0.22`. Change the following instructions as needed for your installation. Unzip `SDL_bgi` archive, then copy: - src/graphics.h -> C:\SDL2-2.0.16\i686-w64-mingw32\include - src/SDL_bgi.h -> C:\SDL2-2.0.16\i686-w64-mingw32\include\SDL2 + src/graphics.h -> C:\SDL2-2.0.22\i686-w64-mingw32\include + src/SDL_bgi.h -> C:\SDL2-2.0.22\i686-w64-mingw32\include\SDL2 bin/DevCpp/SDL_bgi.dll -> C:\DevCpp\MinGW64\bin To learn how to compile programs, please see `howto_DevCpp.md`. @@ -63,6 +67,9 @@ To learn how to compile programs, please see `howto_DevCpp.md`. Windows support is provided for MSYS2 + Mingw-w64 toolchain, CodeBlocks, and Dev-C++. The MSYS2 shell is required. + +## MSYS2 + Mingw-w64 + Please make sure you have SDL2 development packages. You should install `make`, `mingw-w64-x86_64-SDL2`, and `mingw-w64-x86_64-gcc`. **Do not** install plain `gcc`. Also, make sure that directory @@ -73,12 +80,12 @@ install `make`, `mingw-w64-x86_64-SDL2`, and `mingw-w64-x86_64-gcc`. $ # expand the $PATH variable if necessary $ echo export PATH=/mingw64/bin:$PATH >> $HOME/.bashrc - -## MSYS2 + Mingw-w64 +The procedure was tested on `msys2` and its native package +`mingw-w64-x86_64-SDL2` version 2.0.22-1. Start the MSYS2 shell, then run the following commands: - $ VERSION=2.5.0 + $ VERSION=2.5.1 $ tar zxvf SDL_bgi-$VERSION.tar.gz $ cd SDL_bgi-$VERSION/src $ make @@ -99,17 +106,17 @@ To uninstall: Start the MSYS2 shell, then run the following commands: - $ VERSION=2.5.0 + $ VERSION=2.5.1 $ tar zxvf SDL_bgi-$VERSION.tar.gz $ cd SDL_bgi-$VERSION/src $ PATH=/c/CodeBlocks/MinGW/bin/:$PATH && make -f Makefile.CodeBlocks $ make install Assuming that you installed CodeBlocks in `C:\CodeBlocks` and SDL2 -development libraries in in `C:\SDL2-2.0.16`, files will be installed +development libraries in in `C:\SDL2-2.0.22`, files will be installed in these directories: - SDL_bgi_.h -> C:\SDL2-2.0.16\i686-w64-mingw32\include\SDL2 + SDL_bgi_.h -> C:\SDL2-2.0.22\i686-w64-mingw32\include\SDL2 graphics.h -> C:\CodeBlocks\MinGW\include SDL_bgi.dll -> C:\CodeBlocks\MinGW\bin @@ -118,18 +125,18 @@ in these directories: Start the MSYS2 shell, then run the following commands: - $ VERSION=2.5.0 + $ VERSION=2.5.1 $ tar zxvf SDL_bgi-$VERSION.tar.gz $ cd SDL_bgi-$VERSION/src $ PATH=/c/CodeBlocks/MinGW/bin/:$PATH && make -f Makefile.DevCpp $ make install Assuming that you installed Dev-C++ in `C:\DevCpp` and SDL2 -development libraries in in `C:\SDL2-2.0.16`, files will be installed +development libraries in in `C:\SDL2-2.0.22`, files will be installed in these directories: - SDL_bgi_.h -> C:\SDL2-2.0.16\i686-w64-mingw32\include\SDL2 - graphics.h -> C:\SDL2-2.0.16\i686-w64-mingw32\include + SDL_bgi_.h -> C:\SDL2-2.0.22\i686-w64-mingw32\include\SDL2 + graphics.h -> C:\SDL2-2.0.22\i686-w64-mingw32\include SDL_bgi.dll -> C:\DevCpp\MinGW64\bin diff --git a/INSTALL_macOS.md b/INSTALL_macOS.md index 621050d..7dddc50 100644 --- a/INSTALL_macOS.md +++ b/INSTALL_macOS.md @@ -24,7 +24,7 @@ You're now ready to compile `SDL_bgi`. To compile and install `SDL_bgi`, start Terminal and run the following commands: - % VERSION=2.5.0 + % VERSION=2.5.1 % tar xvf SDL_bgi-$VERSION.tar % cd SDL_bgi-$VERSION/src % make diff --git a/README.md b/README.md index 5921625..1fb2e27 100644 --- a/README.md +++ b/README.md @@ -26,26 +26,23 @@ programs, too. `SDL_bgi` should compile on any platform supported by SDL2; it has been tested on GNU/Linux, MS Windows (MSYS2 + Mingw-w64, CodeBlocks, -Dev-C++), macOS (High Sierra and Catalina), and Raspios (ARM, i386). A -few example programs are provided in the `test/` directory. - -If you don't need BGI compatibility, I suggest that you check out -`SDL_gfx`, a graphics library that is more complete and more powerful -than `SDL_bgi`. +Dev-C++), macOS (High Sierra and Catalina), Raspios (ARM, i386), and +WebAssembly (Emscripten). A few example programs are provided in the +`test/` directory. Links: -0. The SDL library: +0. `SDL_bgi` home page: + + +1. The SDL library: -1. BGI on Wikipedia: +2. BGI on Wikipedia: -2. WinBGIm, another BGI Windows port: - - -3. SDL_gfx, graphics drawing primitives and more: - +3. WinBGIm, a BGI port for Windows: + 4. Xbgi, a BGI XLib port: diff --git a/TODO b/TODO index 68ba8c7..8024078 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,7 @@ TODO ---- -- colours as negative numbers: add 16 +- colours as negative numbers (undocumented TC feature): add 16? - documentation: provide an example for each function Your suggestions are welcome! diff --git a/VERSION b/VERSION index 437459c..e70b452 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.5.0 +2.6.0 diff --git a/bin/CodeBlocks/SDL_bgi.dll b/bin/CodeBlocks/SDL_bgi.dll index 6a1f250..cbc044b 100644 Binary files a/bin/CodeBlocks/SDL_bgi.dll and b/bin/CodeBlocks/SDL_bgi.dll differ diff --git a/bin/Dev-Cpp/SDL_bgi.dll b/bin/Dev-Cpp/SDL_bgi.dll index 73f0f15..ec66bab 100644 Binary files a/bin/Dev-Cpp/SDL_bgi.dll and b/bin/Dev-Cpp/SDL_bgi.dll differ diff --git a/bin/Mingw64/SDL_bgi.dll b/bin/Mingw64/SDL_bgi.dll index 19b80ce..2ab9afe 100644 Binary files a/bin/Mingw64/SDL_bgi.dll and b/bin/Mingw64/SDL_bgi.dll differ diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..53208ec --- /dev/null +++ b/doc/README.md @@ -0,0 +1,35 @@ +# README.md + +Documentation in this directory: + +- Compatibility (`compatibility.md`) + +- About internal fonts (`fonts.md`) + +- Functions (`functions.md`) + +- How to compile SDL_bgi programs with Code-Blocks (`howto_CodeBlocks.md`) + +- How to compile SDL_bgi programs with Dev-C++ (`howto_Dev-Cpp.md`) + +- How to turn an `SDL_bgi` program to an AppImage (`making_AppImages.md`) + +- SDL bgi 2.5.1 Quick Reference (`sdl_bgi-quickref.tex`) + +- Turtle Graphics Quick Reference (`turtlegraphics.tex`) + +- Using SDL_bgi (`using.md`) + +- graphics.3.gz (GNU/Linux manpage) + +All `.md` (Markdown) files have been converted to PDF using `pandoc` +and the default PDF engine (pdflatex). If you want to modify these +files and convert them to PDF without a LaTeX installation, a good +alternative is `pdfroff`, provided by the `groff` package: + +```` +pandoc --latex-engine=pdfroff file.md -o file.pdf +```` + +Documents written in LaTeX are typeset with `pdflatex`. + diff --git a/doc/compatibility.md b/doc/compatibility.md index ba449f5..595503a 100644 --- a/doc/compatibility.md +++ b/doc/compatibility.md @@ -15,7 +15,7 @@ complete `GRAPHICS.H` implementation. `SDL_bgi` is a superset of both, and as far as I can say it provides the most compatible `GRAPHICS.H` implementation available. It should -be noted, however, that `SDL_bgi` is not a Turbo C or Borland C++ +be stressed, however, that `SDL_bgi` is not a Turbo C or Borland C++ emulator! Besides, `SDL_bgi` is also designed to be portable and to take advantage of modern graphics hardware, thanks to the SDL2 library. @@ -35,10 +35,10 @@ example, programs written for the `IBM8514.BGI` driver needed modifications to compile and run on the `EGAVGA.BGI` driver. Full compatibility is only possible in a hardware emulator like -DOSBox. If a program uses `CONIO.H`, `DOS.H`, `BIOS.H` and the like, -chances are you won't be able to compile it. Please consider using -DOSBox and one of the original Borland compilers that are available as -freeware. +[DOSBox](https://www.dosbox.com). If a program uses `CONIO.H`, `DOS.H`, +`BIOS.H` and the like, chances are you won't be able to compile it. +Please consider using DOSBox and one of the original Borland compilers +that are available as freeware. That said, `SDL_bgi` is almost perfectly compatible with the original `GRAPHICS.H`. It has been tested on the original `BGIDEMO.C` included @@ -104,6 +104,10 @@ setpalette (RED, COLOR (0xa0, 0x10, 0x10)); setpalette (GREEN, RGBPALETTE (n)); ```` +- console functions (e.g. `printf()`) do not send their output to the +graphics window. If the program was started from a terminal, +input/output will take place on the terminal. + ## Compatibility with WinBGIm diff --git a/doc/compatibility.pdf b/doc/compatibility.pdf index fbfc432..9ff9411 100644 Binary files a/doc/compatibility.pdf and b/doc/compatibility.pdf differ diff --git a/doc/emscripten.md b/doc/emscripten.md new file mode 100644 index 0000000..d6e8d5b --- /dev/null +++ b/doc/emscripten.md @@ -0,0 +1,106 @@ + + +# `SDL_bgi` and Emscripten + +Unmodified `SDL_bgi` programs can be compiled to WebAssembly using the +[Emscripten](https://emscripten.org/) compiler `emcc`; please see +`INSTALL_Emscripten.md`. + +When Emscripten support is installed, the following tools are used to +make standalone `html` files that can be run in browsers without +the need of a local webserver: + +- `test/emcc.sh` can be used to compile a program; +- `test/Makefile.emcc` compiles the sample programs. + +The `emcc` flag `-s ASYNCIFY` is used to simulate infinite loops +without modifiying the program sources, at the expense of some +performance hit. + + +## Compiling Programs + +Compilation example: + +```` +test$ ./emcc.sh life.c +test$ firefox ./life.html & +```` + +The script `emcc.sh` uses one of the available shells in directory +`test/shells`, and embeds files that exist in `test/assets`. Type +`./emcc.sh -h` for a brief explanation. + +To compile nearly all available test programs: + +```` +test$ make -f Makefile.emcc +```` + +Not all programs can be compiled, though. For example, `loadimage.c` +makes no sense when run in a browser; in fact, it expects to find files +in the local file system, which is not accessible by the browser. + +To compile a program directly in the command line: + +```` +test$ emcc --emrun -o program.html program.c -lSDL_bgi \ + -std=gnu99 -O2 -Wall -lm \ + -s USE_SDL=2 -s ALLOW_MEMORY_GROWTH=1 -s ASYNCIFY -s SINGLE_FILE +```` + +The `-s SINGLE_FILE` flag can be omitted if you are running a local +web server. + + +## Available shells + +Emscripten shell files are `html` templates that define how a program +will look when run in the browser. Four shells are provided: + +`sdl_bgi.html`: canvas + text area, no logo + +`shell_minimal.html`: taken from +[Emscripten sources](https://github.com/emscripten-core/emscripten/blob/main/src/shell_minimal.html) + +`canvas_only.html`: canvas only, no text area, no logo + +`fullwindow.html`: canvas only, full window, resizeable, no border. +This shell is quite slow. + +If no shell is specified, the default Emscripten shell will be used. + + +## Environment Files + +Environment variables don't exist in a browser environment. However, +the same result as using variables can be obtained writing +"environment files" in the `assets/` directory. The file +`SDL_BGI_RES`, containing the string `VGA`, will have the same effect +as the environment variable `SDL_BGI_RES`. The same holds for +`SDL_BGI_PALETTE`, value `BGI`. Files must exist at compile time. + + +## Caveats + +SDL2 mutex support is not available in current releases of Emscripten. +Hence, all references to mutex-related functions in `SDL_bgi.c` are +excluded from compilation. For example: + +```` +#ifndef __EMSCRIPTEN__ +static SDL_mutex + *bgi_update_mutex = NULL; +#endif +```` + +As a result, automatic refresh is not available. + +Programs running in fullscreen mode need keyboard input to toggle +fullscreen mode in the browser. diff --git a/doc/emscripten.pdf b/doc/emscripten.pdf new file mode 100644 index 0000000..dcdf42c Binary files /dev/null and b/doc/emscripten.pdf differ diff --git a/doc/fonts.md b/doc/fonts.md index 9f03b35..ca3ce16 100644 --- a/doc/fonts.md +++ b/doc/fonts.md @@ -5,6 +5,7 @@ pandoc -V urlcolor=blue fonts.md -o fonts.pdf ---> + # About internal fonts Internal vector fonts have been decoded from original Borland `.CHR` diff --git a/doc/fonts.pdf b/doc/fonts.pdf index 3033f81..82cd995 100644 Binary files a/doc/fonts.pdf and b/doc/fonts.pdf differ diff --git a/doc/functions.md b/doc/functions.md index 4a0f2a0..f2dd7e3 100644 --- a/doc/functions.md +++ b/doc/functions.md @@ -1,11 +1,9 @@ -SDL_bgi functions and macros -============================ +# SDL_bgi functions and macros This is a list of functions and macros provided by SDL_bgi. -Standard BGI ------------- +## Standard BGI void `arc` (int x, int y, int stangle, int endangle, int radius); @@ -168,8 +166,7 @@ int `textheight` (char \*textstring); int `textwidth` (char \*textstring); -SDL_bgi extensions ------------------- +## SDL_bgi extensions int `ALPHA_VALUE` (int color); @@ -179,8 +176,6 @@ int `COLOR` (int r, int g, int b); int `COLOR32`(Uint32 color); -Uint32 `colorRGB` (int r, int g, int b) (macro) - int `GREEN_VALUE`(int color); int `IS_BGI_COLOR` (int color); @@ -195,6 +190,12 @@ void `_putpixel` (int x, int y); void `closewindow` (int id); +Uint32 `colorRGB` (int r, int g, int b) (macro) + +void `copysurface` (SDL_Surface \*surface, int x1, int y1, int x2, int y2); + +int `doubleclick` (void); + int `event` (void); int `eventtype` (void); @@ -203,6 +204,8 @@ void `getbuffer` (Uint32 \*buffer); int `getcurrentwindow` (void); +int `getclick` (void); + int `getevent` (void); void `getleftclick` (void); @@ -221,7 +224,7 @@ void `getrgbpalette` (struct rgbpalettetype \*, int size); void `getrightclick` (void); -void `getscreensize` (int *x, int *y); +void `getscreensize` (int \*x, int \*y); int `getwindowheight` (void) (macro) @@ -247,7 +250,7 @@ void `readimagefile` (char \*filename, int x1, int y1, int x2, int y2); void `refresh` (void); -void `resetwinoptions` (int id, char *title, int x, int y); +void `resetwinoptions` (int id, char \*title, int x, int y); int `resizepalette` (Uint32); @@ -275,25 +278,26 @@ void `setwinoptions` (char \*title, int x, int y, Uint32 flags); void `setwintitle` (int id, char \*title); -void `showerrorbox` (const char *message); +void `showerrorbox` (const char \*message); -void `showinfobox` (const char *message); +void `showinfobox` (const char \*message); void `swapbuffers` (void); void `writeimagefile` (char \*filename, int left, int top, int right, int bottom); -Non graphics functions ----------------------- +## Non graphics functions void `delay` (int millisec) // DOS.H int `edelay` (int msec); -int `getch` (void); // CONIO.H +int `getch` (void) (macro) // CONIO.H + +int `kbhit` (void) (macro) // CONIO.H -int `kbhit` (void); (macro) // CONIO.H +int `lastkey` (void); int `random` (int range) (macro) // STDLIB.H diff --git a/doc/functions.pdf b/doc/functions.pdf index 80b4a1e..3a8b1b1 100644 Binary files a/doc/functions.pdf and b/doc/functions.pdf differ diff --git a/doc/graphics.3.gz b/doc/graphics.3.gz index 6603dc6..3708071 100644 Binary files a/doc/graphics.3.gz and b/doc/graphics.3.gz differ diff --git a/doc/graphics.3.md b/doc/graphics.3.md index 137f13f..e5e94f4 100644 --- a/doc/graphics.3.md +++ b/doc/graphics.3.md @@ -1,6 +1,6 @@ -% GRAPHICS(3) SDL_bgi 2.5.0 +% GRAPHICS(3) SDL_bgi 2.6.0 % \ -% September 2021 +% May 2022 [1]: # To turn this file to manpage: [2]: # pandoc -s -t man graphics.3.md -o graphics.3 @@ -421,7 +421,7 @@ void *getlinesettings* (struct linesettingstype \*lineinfo); int *getmaxcolor* (void); : Returns the maximum colour value available (*MAXCOLORS*). If ARGB - colours are being used, it returns *PALETTE\_SIZE*. + colours are being used, it returns *PALETTE\_SIZE* (default 4096). int *getmaxmode* (void); : Returns the maximum mode number for the current driver. In *SDL_bgi*, @@ -499,6 +499,9 @@ int *kbhit* (void); : Returns 1 when a key is pressed, excluding special keys (Ctrl, Shift, etc.) +int *lastkey* (void); +: Returns the last key that was detected by *kbhit*(). + void *line* (int x1, int y1, int x2, int y2); : Draws a line between two specified points. @@ -636,10 +639,6 @@ int *COLOR32* (Uint32 color); *setcolor*(), *setbkcolor*(), *setfillpattern*(), and *setfillstyle*() to set a colour as ARGB integer. -Uint32 *colorRGB* (int r, int g, int b) (macro) -: Can be used to compose a 32 bit colour with *r* *g* *b* - components. - int *GREEN_VALUE* (int color); : Returns the green component of *color* in the ARGB palette. @@ -665,6 +664,16 @@ void *\_putpixel* (int x, int y); void *closewindow* (int id); : Closes the window identified by *id*. +Uint32 *colorRGB* (int r, int g, int b) (macro) +: Can be used to compose a 32 bit colour with *r* *g* *b* + components. + +void *copysurface* (SDL_Surface \*surface, int x1, int y1, int x2, int y2); +: Copies *surface* to the rectangle defined by *x1*, *y1*, *x2*, *y2*. + +int *doubleclick* (void); +: Returns 1 if the last mouse click was a double click. + int *edelay* (int msec); : Waits for *msec* milliseconds. This function returns 1 if an event occurs during the delay, otherwise it returns 0. @@ -680,12 +689,15 @@ int *eventtype* (void); void *getbuffer* (Uint32 *buffer); : Copies the contents of the active window to *buffer*. +int *getclick* (void); +: Waits for a mouse button click and returns its code. + int *getcurrentwindow* (void); : Returns the *id* of the current window. int *getevent* (void); : Waits for a keypress, mouse click, or *SDL_QUIT* event, and returns - the code of the key, mouse button, or *SDL_QUIT* + the code of the key, mouse button, or *SDL_QUIT*. void *getleftclick* (void); : Waits for the left mouse button to be clicked and released. @@ -704,8 +716,8 @@ int *getmaxwidth* (void); void *getmiddleclick* (void); : Waits for the middle mouse button to be clicked and released. -void *getmouseclick* (int kind, int \*x, int \*y); -: Sets the *x*, *y* coordinates of the last *kind* button click +void *getmouseclick* (int btn, int \*x, int \*y); +: Sets the *x*, *y* coordinates of the last *btn* button click expected by *ismouseclick*(). void *getrgbpalette* (struct rgbpalettetype\* palette); @@ -724,14 +736,14 @@ void *initpalette* (void); int *initwindow* (int width, int height); : Initializes the graphics system, opening a *width* x *height* - window. + window. Set *width* or *height* equal to 0 to get fullscreen. -int *ismouseclick* (int kind); -: Returns 1 if the *kind* mouse button was clicked. +int *ismouseclick* (int btn); +: Returns 1 if the *btn* mouse button was clicked. int *mouseclick* (void); -: Returns the code of the mouse button that was clicked, or 0 if none - was clicked. +: Returns the code of the mouse button that is being clicked, or + *SDL_MOUSEMOTION*, or 0. int *mousex* (void); : Returns the *X* coordinate of the last mouse click. @@ -822,7 +834,7 @@ int *xkbhit* (void); # ENVIRONMENT *SDL_BGI_RES*: when set to *VGA*, default resolution will be 640 -x 480 instead of 800 x 600. +x 480 instead of default 800 x 600. *SDL_BGI_RATE*: when set to *auto*, automatic screen refresh will be performed. @@ -830,6 +842,10 @@ will be performed. *SDL_BGI_PALETTE*: when set to *BGI*, the first 16 colours will use the same RGB values as Turbo C 2.01. +Compiling programs with *emscripten*, variables *SDL_BGI_RES* and +*SDL_BGI_PALETTE* can be replaced by files by the same name, possibly +containing the strings *VGA* and *BGI*. + # KNOWN BUGS @@ -866,19 +882,50 @@ int main (int argc, char *argv[]) } ``` -To compile this program on GNU/Linux, macOS or Raspios: +To compile this program on GNU/Linux, macOS, or Raspios: ``` $ gcc -o program program.c -lSDL_bgi -lSDL2 ``` -To compile this program in MSYS2 + mingw-w64: +To compile this program on MSYS2 + mingw-w64: ``` $ gcc -o program.exe program.c -lmingw32 -L/mingw64/bin \ -lSDL_bgi -lSDL2main -lSDL2 # -mwindows ``` +To compile this program to WebAssembly using *emcc*: + +``` +$ emcc --emrun -o program.html program.c -lSDL_bgi \ + -std=gnu99 -O2 -Wall -lm \ + -s USE_SDL=2 -s ALLOW_MEMORY_GROWTH=1 -s ASYNCIFY -s SINGLE_FILE +``` + +To initialise the graphics, you may try one of the following methods: + +``` +// open a 400x300 window +initwindow (400, 300); + +// open a 400x300 window, setting position, title, and flags +setwinoptions ("SDL_bgi window", 100, 100, SDL_WINDOW_BORDERLESS); +initwindow (400, 300); + +// go fullscreen +initwindow (0, 0); + +// go fullscreen or VGA if SDL_BGI_RES is set +gd = DETECT; +gm = getmaxmode (); +initgraph(&gd, &gm, ""); + +// go fullscreen with non native resolution +setwinoptions ("", -1, -1, SDL_WINDOW_FULLSCREEN); +initwindow (800, 600); +``` + # AUTHORS Main library: Guido Gonzato, PhD *guido dot gonzato at gmail dot com* @@ -889,8 +936,7 @@ Marco Diego Aurélio Mesquita, *marcodiegomesquita at gmail dot com* # LICENSE *SDL_bgi* is released under the ZLib License. - -Copyright (c) 2014-2021 Guido Gonzato, PhD +opyright (c) 2014-2022 Guido Gonzato, PhD This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -907,4 +953,3 @@ freely, subject to the following restrictions: 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. - diff --git a/doc/howto_AppImage.md b/doc/howto_AppImage.md new file mode 100644 index 0000000..42124d6 --- /dev/null +++ b/doc/howto_AppImage.md @@ -0,0 +1,159 @@ + + + +# How to turn an `SDL_bgi` program to an AppImage + +AppImages are GNU/Linux programs that run on any GNU/Linux distro (if +they're packaged correctly!) An AppImage is single file containing the +program binary, libraries, and other resources; it can be made +executable and run without installation. Please see + + +This document explains how to turn an `SDL_bgi` program to an +AppImage. We will use the sample program `fern.c`, included in +the `test/` directory in the `SDL_bgi` sources. It assumes that +`SDL_bgi` has been installed. + +The procedure described below has been tested on fresh Ubuntu 18.04 +and 20.04 systems. AppImages created on either platform also worked on +the other; however, AppImages built on Ubuntu 18.04 are much smaller. + +A tutorial is available [here]( +https://appimage-builder.readthedocs.io/en/latest/intro/tutorial.html) +but, IMHO, it needs some improvement. + + +## Software + +Assuming we are building on the x86_64 architecture, we need two +programs: + +- `appimagetool-x86_64.AppImage` + +available here: + + +- `appimage-builder` + +available here: + + +First of all, install some required software: + +```` +$ sudo apt install -y python3-pip python3-setuptools patchelf \ +desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace fuse \ +python3-imagesize gtk-update-icon-cache +```` + +Install `appimagetool` somewhere in your `$PATH`; I suggest that you +install in `$HOME/.local/bin`. Make sure that this directory is +included in your `$PATH`. + +```` +$ wget https://github.com/AppImage/AppImageKit/\ +releases/download/continuous/appimagetool-x86_64.AppImage \ +-O $HOME/.local/bin/appimagetool +```` + +Install `appimage-builder` using `pip3`. Required Python packages will +be installed in `$HOME/.local/lib/python3.8`; `appimage-builder` will +be installed in `$HOME/.local/bin`. + +```` +$ pip3 install --user appimage-builder +```` + +All necessary software is now installed, and we are ready to build the +AppImage. + + +## Making the AppImage + +We need three files: the program executable, an icon, and the +`libSDL_bgi.so` library. + +Create the `AppDir` directory tree, which will contain the files. If +this directory tree already exists, remove it. This directory can be +created anywhere. + +```` +~$ rm -rf AppDir ; \ + mkdir -p AppDir/usr/bin \ + AppDir/lib/x86_64 \ + AppDir/usr/share/icons/fern/256x256/ +```` + +Compile the `fern` application: + +```` +test$ gcc -o fern fern.c -lSDL_bgi -lSDL2 +test$ cp fern $HOME +```` + +A 256x256 icon, `icon.png`, is available in the `SDL_bgi` sources in +`doc/`: + +```` +doc$ cp icon.png $HOME +```` + +Find out the location of `libSDL_bgi.so`: + +```` +~$ locate libSDL_bgi.so +/usr/lib/x86_64-linux-gnu/libSDL_bgi.so +~$ cp /usr/lib/x86_64-linux-gnu/libSDL_bgi.so . +```` + +Copy the `fern` executable, `icon.png`, and `libSDL_bgi.so` to the right +directories: + +```` +$ cp fern AppDir/usr/bin/ ; \ + cp icon.png AppDir/usr/share/icons/fern/256x256/ ; \ + cp libSDL_bgi.so AppDir/lib/x86_64/ +```` + +Create the so-called "recipe" for the AppImage: + +```` +$ appimage-builder --generate +INFO:Generator:Searching AppDir +? ID [Eg: com.example.app]: fern +? Application Name: Fern +? Icon: icon +? Executable path relative to AppDir [usr/bin/app]: usr/bin/fern +? Arguments [Default: $@]: $@ +? Version [Eg: 1.0.0]: 1.0.0 +? Update Information [Default: guess]: guess +? Architecture: x86_64 +... +INFO:Generator:Recipe generation completed. +```` + +The application should run; if it doesn't, the final AppImage might be +defective. The `AppImageBuilder.yml` recipe file will be created. + +The last stage builds the AppImage, skipping the `test` phase that +only works if you have `docker` installed. + +```` +$ appimage-builder --skip-test --recipe AppImageBuilder.yml +INFO:main:Running main script +INFO:main:Running apt deploy +INFO:apt:apt-get update +... +INFO:root:AppImage created successfully +```` + +If everything worked as expected, you will find the newly created +AppImage called `Fern-1.0.0-x86_64.AppImage`. If you plan to +distribute the app, please check if it works on other Linux distros +beforehand. diff --git a/doc/howto_AppImage.pdf b/doc/howto_AppImage.pdf new file mode 100644 index 0000000..4f54362 Binary files /dev/null and b/doc/howto_AppImage.pdf differ diff --git a/doc/howto_CodeBlocks.md b/doc/howto_CodeBlocks.md index 146af09..2154c68 100644 --- a/doc/howto_CodeBlocks.md +++ b/doc/howto_CodeBlocks.md @@ -14,11 +14,11 @@ CodeBlocks; we will use `fern.c`, provided in the `test/` directory. Let's assume that CodeBlocks is installed in `C:\CodeBlocks`, and that the SDL2 development libraries for MinGW are installed in -`C:\SDL2-2.0.16`. If you installed the software in different +`C:\SDL2-2.0.22`. If you installed the software in different directories, change the following instructions accordingly. -The procedure was tested with CodeBlocks 20.02 and -SDL2-devel-2.0.16-mingw.tar.gz. +The procedure was tested with CodeBlocks 20.03 and +SDL2-devel-2.0.22-mingw.tar.gz. Links: @@ -34,10 +34,10 @@ Installing `SDL_bgi` `C:\CodeBlocks\MinGW\bin` - copy `SDL_bgi.h` to\ - `C:\SDL2-2.0.16\x86_64-w64-mingw32\include\SDL2` + `C:\SDL2-2.0.22\x86_64-w64-mingw32\include\SDL2` - copy `graphics.h` to\ - `C:\SDL2-2.0.16\x86_64-w64-mingw32\include` + `C:\SDL2-2.0.22\x86_64-w64-mingw32\include` How to compile @@ -51,7 +51,7 @@ How to compile store the project, then click on `Next>` - in the next window (SDL2 location), pick - `C:\SDL2-2.0.16\x86_64-w64-mingw32`, then click on `Next>` + `C:\SDL2-2.0.22\x86_64-w64-mingw32`, then click on `Next>` - in the next window, uncheck `Create "Debug" configuration`, check `Create "Release" configuration`, then click on `Finish` @@ -64,13 +64,13 @@ How to compile - from the menu `Project/Build options...` select the `Search directories` tab, click on `Add`, pick the directory\ - `C:\SDL2-2.0.16\x86_64-w64-mingw32\include`, then select `No` when + `C:\SDL2-2.0.22\x86_64-w64-mingw32\include`, then select `No` when asked to `Keep this as a relative path?`. Click on `Ok` - from the menu `Project/Build options...` select the `Linker settings` tab, click on `Add`, pick the files\ `C:\CodeBlocks\MinGW\bin\SDL_bgi.dll` and\ - `C:\SDL2-2.0.16\x86_64-w64-mingw32\bin\SDL2.dll`, then select + `C:\SDL2-2.0.22\x86_64-w64-mingw32\bin\SDL2.dll`, then select `No` when asked to `Keep this as a relative path?`. Click on `Ok` - from the menu `Build`, select `Build`. The executable `fern.exe` diff --git a/doc/howto_CodeBlocks.pdf b/doc/howto_CodeBlocks.pdf index 9d245f5..4e239be 100644 Binary files a/doc/howto_CodeBlocks.pdf and b/doc/howto_CodeBlocks.pdf differ diff --git a/doc/howto_Dev-Cpp.md b/doc/howto_Dev-Cpp.md index f6294f3..b39ffbe 100644 --- a/doc/howto_Dev-Cpp.md +++ b/doc/howto_Dev-Cpp.md @@ -14,11 +14,12 @@ Dev-C++; we will use `fern.c`, provided in the `test/` directory. Let's assume that Dev-C++ is installed in `C:\Dev-Cpp`, and that the SDL2 development libraries for MinGW are installed in -`C:\SDL2-2.0.16`. If you installed the software in different +`C:\SDL2-2.0.22`. If you installed the software in different directories, change the following instructions accordingly. -The procedure was tested with Orwell Dev-Cpp 5.11, TDM64-GCC 9.2.0, -and SDL2-devel-2.0.16-mingw.tar.gz. +The procedure was tested with Orwell Dev-Cpp 5.11, TDM64-GCC 10.3.0, +and SDL2-devel-2.0.22-mingw.tar.gz. Newer releases of these packages +should work. Links: @@ -49,7 +50,7 @@ a newer release. - when asked to `Clear current compiler list?`, click on `Yes` -- `TDM-GCC 9.2.0 64-bit release` will be set as the `Compiler set to +- `TDM-GCC 10.3.0 64-bit release` will be set as the `Compiler set to configure`. Click on `Ok` - test Dev-C++ and make sure that you can compile programs. @@ -62,10 +63,10 @@ Installing `SDL_bgi` `C:\Dev-Cpp\MinGW64\lib` - copy `src/SDL_bgi.h` to\ - `C:\SDL2-2.0.16\x86_64-w64-mingw32\include\SDL2` + `C:\SDL2-2.0.22\x86_64-w64-mingw32\include\SDL2` - copy `src/graphics.h` to\ - `C:\SDL2-2.0.16\x86_64-w64-mingw32\include` + `C:\SDL2-2.0.22\x86_64-w64-mingw32\include` How to compile @@ -86,16 +87,16 @@ How to compile `C:\Dev-Cpp\MinGW64\lib` - tab `Directories`, tab `Include Directories`: add\ - `C:\SDL2-2.0.16\x86_64-w64-mingw32\include\SDL2` and\ - `C:\SDL2-2.0.16\x86_64-w64-mingw32\include` + `C:\SDL2-2.0.22\x86_64-w64-mingw32\include\SDL2` and\ + `C:\SDL2-2.0.22\x86_64-w64-mingw32\include` - tab `Library Directories`: add\ - `C:\SDL2-2.0.16\x86_64-w64-mingw32\lib` and\ + `C:\SDL2-2.0.22\x86_64-w64-mingw32\lib` and\ `C:\Dev-Cpp\MinGW64\lib` then click on Ok - compile the program: menu `Execute/Compile` -- copy ``C:\SDL2-2.0.16\x86_64-w64-mingw32\bin\SDL2.dll` and\ +- copy ``C:\SDL2-2.0.22\x86_64-w64-mingw32\bin\SDL2.dll` and\ `SDL_bgi.dll` to the same directory as `fern.exe` - run it: menu `Execute/Run`. diff --git a/doc/howto_Dev-Cpp.pdf b/doc/howto_Dev-Cpp.pdf index 3b4e8f3..585a06d 100644 Binary files a/doc/howto_Dev-Cpp.pdf and b/doc/howto_Dev-Cpp.pdf differ diff --git a/doc/icon.png b/doc/icon.png new file mode 100644 index 0000000..2a56dbe Binary files /dev/null and b/doc/icon.png differ diff --git a/doc/sdl_bgi-quickref.pdf b/doc/sdl_bgi-quickref.pdf index b214dbf..6481c9a 100644 Binary files a/doc/sdl_bgi-quickref.pdf and b/doc/sdl_bgi-quickref.pdf differ diff --git a/doc/sdl_bgi-quickref.tex b/doc/sdl_bgi-quickref.tex index af2b951..cce6212 100644 --- a/doc/sdl_bgi-quickref.tex +++ b/doc/sdl_bgi-quickref.tex @@ -1,7 +1,7 @@ % sdl_bgi-quickref.tex % % Guido Gonzato, PhD -% September 14, 2021 +% May 28, 2022 \documentclass[a4paper,12pt]{article} \usepackage{graphicx} @@ -21,7 +21,7 @@ \setlength{\parindent}{0pt} \setlength{\parskip}{3pt} -\newcommand{\version}{2.5.0} % !!! <<<=== Change here !!! +\newcommand{\version}{2.6.0} % !!! <<<=== Change here !!! \newcommand{\V}{\texttt{void}} % void \newcommand{\I}{\texttt{int}} % int @@ -79,12 +79,13 @@ \section{Introduction to \SDLbgi} -\SDLbgi{} is a multiplatform, fast, SDL2-based implementation of BGI: -the Borland Graphics Interface also known as \T{GRAPHICS.H}. BGI -was a graphics library provided by Borland Turbo C / Borland C++ -compilers for DOS, and it was very popular in the late eighties--early -nineties. It became the \emph{de facto} standard for computer -graphics, especially in education. For more information, please see +\href{https://sdl_bgi.sourceforge.net}{\SDLbgi} is a multiplatform, +fast, SDL2-based implementation of BGI: the Borland Graphics Interface +also known as \T{GRAPHICS.H}. BGI was a graphics library provided by +Borland Turbo C / Borland C++ compilers for DOS, and it was very +popular in the late eighties--early nineties of the last century. It +became the \emph{de facto} standard for computer graphics, especially +in education. For more information, please see \href{https://en.wikipedia.org/wiki/Borland_Graphics_Interface}{the Wikipedia article}. @@ -100,12 +101,12 @@ \section{Introduction to \SDLbgi} for more information on WinBGIm. \SDLbgi{} is one of the easiest libraries to do graphics programming -in C. It is much simpler to use than SDL2, OpenGL and the like; +in C. It is much simpler to use than plain SDL2, OpenGL and the like; obviously, it's less complete. Teachers may find \SDLbgi{} a useful tool for introductory computer graphics courses. -This is a minimal program that opens a window and draws 1000 random -lines: +For example, this is a minimal program that opens a window and draws +1000 random lines: \begin{small} \begin{spacing}{0.9} @@ -115,7 +116,7 @@ \section{Introduction to \SDLbgi} int main (int argc, char *argv[]) { int i, gd = DETECT, gm; - initgraph (&gd, &gm, "C:\\TC\\BGI"); // default: 800 x 600 + initgraph (&gd, &gm, ""); // default: 800 x 600 setbkcolor (BLACK); cleardevice (); outtextxy (0, 0, "Drawing 1000 lines..."); @@ -148,6 +149,9 @@ \section{Introduction to \SDLbgi} defined, with or without clipping. All of these parameters can be changed using appropriate functions. +\SDLbgi{} programs can be compiled to native code on several +platforms, and also to WebAssembly using Emscripten. + % ----- \subsection{Constants} @@ -168,13 +172,16 @@ \subsection{Constants} #include #include #include - #include // for fprintf() #include // for exit(), calloc() #include // for sin(), cos() #include // for strlen(), memcpy() -#define SDL_BGI_VERSION 2.5.0 +#ifdef __EMSCRIPTEN__ +#include +#endif + +#define SDL_BGI_VERSION 2.6.0 enum { NOPE, YEAH } ; #define BGI_WINTITLE_LEN 512 // more than enough @@ -278,15 +285,25 @@ \subsection{Constants} USER_FILL // user defined fill }; -// mouse buttons +// mouse events - compatible with WinBGIm + +#define WM_MOUSEMOVE SDL_MOUSEMOTION + +#define WM_LBUTTONDOWN SDL_BUTTON_LEFT +#define WM_LBUTTONUP SDL_MOUSEBUTTONUP + SDL_BUTTON_LEFT +#define WM_LBUTTONDBLCLK SDL_MOUSEBUTTONDOWN + SDL_BUTTON_LEFT + 2 + +#define WM_MBUTTONDOWN SDL_BUTTON_MIDDLE +#define WM_MBUTTONUP SDL_MOUSEBUTTONUP + 10*SDL_BUTTON_MIDDLE +#define WM_MBUTTONDBLCLK SDL_MOUSEBUTTONDOWN + 10*SDL_BUTTON_MIDDLE + 2 -#define WM_LBUTTONDOWN SDL_BUTTON_LEFT -#define WM_MBUTTONDOWN SDL_BUTTON_MIDDLE -#define WM_RBUTTONDOWN SDL_BUTTON_RIGHT -#define WM_WHEEL SDL_MOUSEWHEEL -#define WM_WHEELUP SDL_USEREVENT -#define WM_WHEELDOWN SDL_USEREVENT + 1 -#define WM_MOUSEMOVE SDL_MOUSEMOTION +#define WM_RBUTTONDOWN SDL_BUTTON_RIGHT +#define WM_RBUTTONUP SDL_MOUSEBUTTONUP + 20*SDL_BUTTON_RIGHT +#define WM_RBUTTONDBLCLK SDL_MOUSEBUTTONDOWN + 20*SDL_BUTTON_RIGHT + 2 + +#define WM_WHEEL SDL_MOUSEWHEEL +#define WM_WHEELUP SDL_BUTTON_RIGHT + 1 +#define WM_WHEELDOWN SDL_BUTTON_RIGHT + 2 // keys #define KEY_HOME SDLK_HOME @@ -387,6 +404,29 @@ \subsection{Constants} grInvalidVersion = -18 }; +// libXbgi compatibility + +#define X11_CGALO SDL_CGALO +#define X11_CGAHI SDL_CGAHI +#define X11_EGA SDL_EGA +#define X11 SDL +#define X11_VGA SDL_VGA +#define X11_640x480 SDL_640x480 +#define X11_HERC SDL_HERC +#define X11_PC3270 SDL_PC3270 +#define X11_SVGALO SDL_SVGALO +#define X11_800x600 SDL_800x600 +#define X11_SVGAMED1 SDL_SVGAMED1 +#define X11_1024x768 SDL_1024x768 +#define X11_SVGAMED2 SDL_SVGAMED2 +#define X11_1152x900 SDL_1152x900 +#define X11_SVGAHI SDL_SVGAHI +#define X11_1280x1024 SDL_1280x1024 +#define X11_WXGA SDL_WXGA +#define X11_1366x768 SDL_1366x768 +#define X11_USER SDL_USER +#define X11_FULLSCREEN SDL_FULLSCREEN + // structs struct arccoordstype { @@ -450,7 +490,7 @@ \subsection{Constants} \subsection{Environment Variables} \T{SDL\_BGI\_RES}: when set to \T{VGA}, default resolution will be 640 -$\times$ 480 instead of 800 $\times$ 600. Please see +$\times$ 480 instead of default 800 $\times$ 600. Please see \func{initgraph()} (page \pageref{sec:initgraph}) for details. \T{SDL\_BGI\_RATE}: when set to \T{auto}, automatic screen refresh @@ -517,7 +557,7 @@ \subsection{Note for SDL2 Programmers} SDL_Window *bgi_window; SDL_Renderer *bgi_renderer; SDL_Texture *bgi_texture; -extern Uint32 PALETTE_SIZE; +Uint32 PALETTE_SIZE; \end{verbatim} \end{spacing} \end{small} @@ -540,6 +580,8 @@ \subsection{Note for SDL2 Programmers} \end{spacing} \end{small} +Please see \file{test/loadimage.c} for a complete example. + % ----- \section{Standard BGI Graphics Functions} @@ -647,7 +689,8 @@ \section{Standard BGI Graphics Functions} \V{} \func{closegraph} (\V{}); \end{bgi} -Closes the graphics system. +Closes the graphics system. In Emscripten, it closes the browser tab +or window. % ----- @@ -1133,8 +1176,7 @@ \section{Standard BGI Graphics Functions} every \A{msec} milliseconds. Automatic screen refresh is much faster than the default behaviour; -however, it is an experimental feature that may not work on some -graphic cards. +however, this feature may not work on some graphic cards. % ----- @@ -1643,6 +1685,17 @@ \section{Non-Graphics Functions and Macros} % ----- +\addcontentsline{toc}{subsection}{\T{lastkey()}} +\phantomsection\label{sec:lastkey} + +\begin{bgi} +\I{} \func{lastkey} (\V{}); +\end{bgi} + +Returns the last key that was detected by \func{kbhit()}. + +% ----- + \addcontentsline{toc}{subsection}{\T{random()}} \phantomsection\label{sec:random} @@ -1695,16 +1748,16 @@ \section{\SDLbgi{} Additions} \I{} \func{COLOR} (\I{} \A{r}, \I{} \A{g}, \I{} \A{b}); \end{bgi} -Can be used as colour argument for \func{getbkcolor()}, -\func{getcolor()}, \func{putpixel()}, \func{setbkcolor()} -\func{setbkcolor()}, \func{setcolor()}, \func{setfillpattern()}, -\func{setfillstyle()} and \func{setpalette()} to set a colour +Can be used as colour argument for \func{getbkcolor()},\ +\func{getcolor()},\ \func{putpixel()},\ \func{set\-bkcolor()} +\func{setbkcolor()},\ \func{setcolor()},\ \func{setfillpattern()}, +\func{setfillstyle()},\ and \func{setpalette()}\ to set a colour specifying its ARGB components. The colour index is \T{ARGB\_TMP\_COL}. Functions \func{ALPHA\_VALUE()}, \func{BLUE\_VALUE()}, -\func{GREEN\_VALUE()}, and \func{RED\_VALUE()} do not work on temporary -colours. +\func{GREEN\_VALUE()}, and \func{RED\_VALUE()} do not work on +temporary colours. % ----- @@ -1715,15 +1768,15 @@ \section{\SDLbgi{} Additions} \I{} \func{COLOR32} (\I{} \Ut{color}); \end{bgi} -Can be used as colour argument for \func{getbkcolor()}, -\func{getcolor()}, \func{putpixel()}, \func{setbkcolor()} -\func{setbkcolor()}, \func{setcolor()}, \func{setfillpattern()}, -\func{setfillstyle()} and \func{setpalette()} to set a colour as ARGB -integer. The colour index is \T{ARGB\_TMP\_COL}. +Can be used as colour argument for \func{getbkcolor()},\ +\func{getcolor()},\ \func{putpixel()},\ \func{set\-bkcolor()},\ +\func{setcolor()},\ \func{setfillpattern()},\ \func{setfillstyle()},\ +and \func{setpalette()} to set a colour as ARGB integer. The colour +index is \T{ARGB\_TMP\_COL}. Functions \func{ALPHA\_VALUE()}, \func{BLUE\_VALUE()}, -\func{GREEN\_VALUE()}, and \func{RED\_VALUE()} do not work on temporary -colours. +\func{GREEN\_VALUE()}, and \func{RED\_VALUE()} do not work on +temporary colours. % ----- @@ -1829,6 +1882,28 @@ \section{\SDLbgi{} Additions} % ----- +\addcontentsline{toc}{subsection}{\T{copysurface()}} +\phantomsection\label{sec:copysurface} + +\begin{bgi} +\V{} \func{copysurface} (\T{SDL\_Surface} \A{surface}, +\I{} \A{x1}, \I{} \A{y1}, \I{} \A{x2}, \I{} \A{y2}); +\end{bgi} + +Copies \A{surface} to the rectangle defined by \A{x1}, \A{y1}, \A{x2}, +\A{y2} and displays it immediately. If \A{x2} or \A{y2} equals 0, then +the original surface size will be used. + +% ----- + +\begin{bgi} +\I{} \func{doubleclick} (\V{}); +\end{bgi} + +Returns 1 if the last mouse click was a double click. + +% ----- + \begin{bgi} \I{} \func{edelay} (\I{} \A{msec}); \end{bgi} @@ -1847,8 +1922,9 @@ \section{\SDLbgi{} Additions} \I{} \func{event} (\V{}); \end{bgi} -Returns 1 if an event (mouse click, key press, or \T{SDL\_QUIT}) has -occurred. +Returns 1 if one of the following events has occurred: +\T{SDL\_KEYDOWN}, \T{SDL\_MOU\-SEBUT\-TONDOWN}, \T{SDL\_MOUSEWHEEL}, +or \T{SDL\_QUIT}; 0 otherwise. % ----- @@ -1859,8 +1935,9 @@ \section{\SDLbgi{} Additions} \I{} \func{eventtype} (\V{}); \end{bgi} -Returns the type of the last event; either \T{SDL\_KEYPRESS} or -\T{SDL\_MOUSEBUTTONDOWN}. +Returns the type of the last event. Reported events are +\T{SDL\_KEYDOWN}, \T{SDL\_MOUSEMOTION}, \T{SDL\_MOUSEBUTTONDOWN}, +\T{SDL\_MOUSEBUTTONUP}, \T{SDL\_MOUSEWHEEL}, and \T{SDL\_QUIT}. % ----- @@ -1877,6 +1954,17 @@ \section{\SDLbgi{} Additions} % ----- +\addcontentsline{toc}{subsection}{\T{getclick()}} +\phantomsection\label{sec:getclick} + +\begin{bgi} +\I{} \func{getclick} (\V{}); +\end{bgi} + +Waits for a mouse click and returns the button that was clicked. + +% ----- + \addcontentsline{toc}{subsection}{\T{getcurrentwindow()}} \phantomsection\label{sec:getcurrentwindow} @@ -1895,8 +1983,10 @@ \section{\SDLbgi{} Additions} \I{} \func{getevent} (\V{}); \end{bgi} -Waits for a keypress, mouse click, or \T{SDL\_QUIT} event, and returns -the code of the key, mouse button, or \T{QUIT}. +Waits for one of the following events: \T{SDL\_KEYDOWN}, +\T{SDL\_MOUSEBUTTONDOWN}, \T{SDL\_MOU\-SEWHEEL}, and \T{SDL\_QUIT}. It +returns the code of the key, or the mouse button, either +\T{WM\_WHEELUP} or \T{WM\_WHEELDOWN}, or \T{SDL\_QUIT}. % ----- @@ -2079,8 +2169,9 @@ \section{\SDLbgi{} Additions} \I{} \func{mouseclick} (\V{}); \end{bgi} -Returns the code of the mouse button that was clicked, or 0 if none -was clicked. +Returns the code of the mouse button that is being clicked, or +\T{SDL\_MOUSEMOTION} if the mouse is being moved, or 0 if no mouse +event is occurring. % ----- diff --git a/doc/using.md b/doc/using.md index 1cd2cb5..ff4b8fe 100644 --- a/doc/using.md +++ b/doc/using.md @@ -8,6 +8,12 @@ # Using `SDL_bgi` +If you're familiar with BGI, the Borland Graphics Interface +(`GRAPHICS.H`) provided by Turbo C or Borland C++, then using +`SDL_bgi` along with `gcc` or `clang` will be straighforward. If you +don't even know what BGI was, don't worry: you will find `SDL_bgi` an +easy and fun way to do graphics programming in C. + Although `SDL_bgi` is almost perfectly compatible with the original `GRAPHICS.H` by Borland, a few minor differences have been introduced. The original BGI library mainly targeted the VGA video display @@ -19,17 +25,34 @@ colours. `SDL_bgi` uses modern graphics capabilities provided by ## Compiling Programs To compile a C or C++ program on GNU/Linux, macOS or Raspios you can -use the `gcc` or `clang` compiler: +use the `gcc`,`clang`, or `tcc` compilers. With `gcc` or `clang`: $ gcc -o program program.c -lSDL_bgi -lSDL2 +With `tcc`: + + $ tcc -o program program.c -w -D SDL_DISABLE_IMMINTRIN_H \ + -I /usr/include/SDL2 -lSDL_bgi -lSDL2 + +You may get compilation errors affecting `libpulsecommon`; they can be +safely ignored. + +`tcc` can also be invoked from scripts. You just need to add the +following line (it can't be split with `\`) at the start of your C +source (GNU/Linux): + + #!/usr/bin/tcc -run -w -D SDL_DISABLE_IMMINTRIN_H -I /usr/include/SDL2 -lSDL_bgi -lSDL2 + +but for better compatibility, please have a look at the `test/tccrun` +script. + To compile a program in MSYS2 + mingw-w64: $ gcc -o program.exe program.c -lmingw32 -L/mingw64/bin \ -lSDL_bgi -lSDL2main -lSDL2 # -mwindows The `-mwindows` switch creates a window-only program, i.e. a terminal -is not started. **Beware:** functions provided by `stdio.h` will not +is not started. *Beware:* functions provided by `stdio.h` will not work if you don't start a terminal; your program will have to rely on mouse input only. @@ -37,7 +60,25 @@ Code::Blocks users should read the file `howto_CodeBlocks.md`. Dev-C++ users should read the file `howto_Dev-Cpp.md`. -Windows users **must** declare the `main()` function as: +To compile a program to WebAsssembly using `emcc`: + + $ emcc -o program.html program.c \ + -std=gnu99 -O2 -Wall -lSDL_bgi -lm \ + -s USE_SDL=2 `# uses SDL2 module` \ + -s ALLOW_MEMORY_GROWTH=1 `# needed for the argb palette` \ + -s ASYNCIFY `# implement loops` \ + -s SINGLE_FILE `# standalone html files` + +where `SDL_bgi.bc` is the precompiled `SDL_bgi` wasm module. +The resulting `program.html` can be loaded and run in web browsers, +without the need of starting a local web server: + + $ firefox program.html + + +### Compilation details + +Windows users *must* declare the `main()` function as: int main (int argc, char *argv[]) @@ -54,7 +95,8 @@ unmodified. For instance, initgraph (&gd, &gm, ""); opens an 800x600 window, mimicking SVGA graphics. If the environment -variable `SDL_BGI_RES` is `VGA`, window resolution will be 640x480. +variable `SDL_BGI_RES` is set to `VGA`, window resolution will be +640x480. Minimal `dos.h` and `conio.h` are provided in the `test/` directory; they're good enough to compile the original `bgidemo.c`. @@ -112,7 +154,7 @@ new function `refresh()`. The first method is fully compatible with the original BGI, but it also painfully slow. An experimental feature is 'auto mode': if the environment variable `SDL_BGI_RATE` is set to `auto`, screen refresh -is automatically performed; this is **much** faster than the default. +is automatically performed; this is *much* faster than the default. This variable may also contain a refresh rate; e.g. 60. Unfortunately, auto mode may not work on some NVIDIA graphic cards. @@ -127,7 +169,7 @@ Documentation and sample BGI programs are available at this address: Nearly all programs can be compiled with `SDL_bgi`. -The original Borland Turbo C 2.0 manual is also available at: +The original Borland Turbo C 2.0 manual is also available here: . @@ -220,7 +262,8 @@ and can be used by native SDL2 functions; see example in ### Screen and Windows Functions - `void initwindow(int width, int height)` lets you open a window -specifying its size. +specifying its size. If either `width` or `height` is 0, then +`SDL_FULLSCREEN` will be used. - `void detectgraph(int *gd, int *gm)` returns `SDL`, `SDL_FULLSCREEN`. @@ -331,9 +374,9 @@ on a single line of pixels at `y` coordinate. ### Mouse Functions -- `int mouseclick(void)` returns the code of the mouse button that was -clicked, or 0 if none was clicked. Mouse buttons and movement -constants are defined in `SDL_bgi.h`: +- `int mouseclick(void)` returns the code of the mouse button that +is being clicked, 0 otherwise. Mouse buttons and movement constants +are defined in `SDL_bgi.h`: ``` WM_LBUTTONDOWN @@ -345,6 +388,10 @@ WM_WHEELDOWN WM_MOUSEMOVE ``` +- `int isdoubleclick(void)` returns 1 if the last mouse click was a +double click. + + - `int mousex(void)` and `int mousey(void)` return the mouse coordinates of the last click. @@ -358,6 +405,9 @@ coordinates of the last button click expected by `ismouseclick()`. getrightclick(void)` wait for the left, middle, and right mouse button to be clicked and released. +- `int getclick(void)` waits for a mouse click and returns the button +that was clicked. + ### Miscellaneous Functions @@ -395,6 +445,8 @@ int bottom)` writes a `.bmp` file from the screen rectangle defined by - `void kbhit(void)` returns 1 when a key is pressed, excluding Shift, Alt, etc. +- `int lastkey(void)` returns the last key that was detected by + `kbhit()`. - `void xkbhit(void)` returns 1 when any key is pressed, including Shift, Alt, etc. diff --git a/doc/using.pdf b/doc/using.pdf index f8bfb2a..71b30dd 100644 Binary files a/doc/using.pdf and b/doc/using.pdf differ diff --git a/mkpkg.sh b/mkpkg.sh new file mode 100644 index 0000000..31047f3 --- /dev/null +++ b/mkpkg.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +# This script builds .deb and/or .rpm packages +# on GNU/Linux + +if [ $(uname) != "Linux" ] ; then + echo "This script is for GNU/Linux only." + exit 1 +fi + +VERSION=$(cat VERSION) + +mkdir -p build && cd build/ +cmake -DCMAKE_INSTALL_PREFIX=/usr .. +PACKAGE_DONE=0 + +# is this system .deb based? +DEB=$(which dpkg 2> /dev/null) +if [ $? = 0 ] ; then + DEB_ARCH=$(dpkg --print-architecture) + printf "\n*** This system looks Debian-based.\n\n" + cpack -G "DEB" .. + DEB_NAME="sdl_bgi_"$VERSION"-1_"$DEB_ARCH".deb" + /bin/mv *deb $DEB_NAME + printf "\n*** Package $DEB_NAME created in subdirectory build/.\n\n" + PACKAGE_DONE=1 +fi + +# is this system .rpm based? +RPM=$(which rpm 2> /dev/null) +if [ $? = 0 ] ; then + RPM_ARCH=$(uname -m) + printf "\n*** This system looks RPM-based.\n\n" + cpack -G "RPM" .. + RPM_NAME="SDL_bgi-"$VERSION"-1."$RPM_ARCH".rpm" + /bin/mv *rpm $RPM_NAME + printf "\n*** Package $RPM_NAME created in subdirectory build/.\n\n" + PACKAGE_DONE=1 +fi + +if [ $PACKAGE_DONE = 0 ] ; then + printf "\n*** I don't know what package to build.\n\n" +fi diff --git a/sdl_bgi.spec b/sdl_bgi.spec index 50f7293..f15759f 100644 --- a/sdl_bgi.spec +++ b/sdl_bgi.spec @@ -4,12 +4,12 @@ Summary: SDL2-based 'GRAPHICS.H' implementation Name: SDL_bgi -Version: 2.5.0 +Version: 2.6.0 Release: 1 License: ZLib Group: Libraries Source: %{name}-%{version}.tar.gz -URL: http://libxbgi.sourceforge.net/ +URL: http://sdl_bgi.sourceforge.net/ BuildRequires: SDL2-devel Prefix: %{_prefix} BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot @@ -20,7 +20,7 @@ based on SDL2. This library strictly emulates BGI functions, making it possible to compile SDL2 versions of programs written for Turbo C/Borland C++. ARGB colours, vector fonts, mouse support, and multiple windows are also implemented; further, native SDL2 functions may be -used in SDL_bgi programs. +used in SDL_bgi programs. SDL_bgi also supports Wasm via Emscripten. %prep %setup -q -n %{name}-%{version} @@ -35,27 +35,38 @@ cd src mkdir -p $RPM_BUILD_ROOT/%{_libdir} mkdir -p $RPM_BUILD_ROOT/%{_includedir} mkdir -p $RPM_BUILD_ROOT/%{_includedir}/SDL2/ +mkdir -p $RPM_BUILD_ROOT/%{_docdir}/%{name}/test/assets/ +mkdir -p $RPM_BUILD_ROOT/%{_docdir}/%{name}/test/shells/ mkdir -p $RPM_BUILD_ROOT/%{_mandir}/man3/ /usr/bin/install -m 644 graphics.h $RPM_BUILD_ROOT/%{_includedir} /usr/bin/install -m 644 SDL_bgi.h $RPM_BUILD_ROOT/%{_includedir}/SDL2/ /usr/bin/install -m 644 lib%{name}.so $RPM_BUILD_ROOT/%{_libdir} cd ../doc/ /usr/bin/install -m 644 graphics.3.gz $RPM_BUILD_ROOT/%{_mandir}/man3/ +cd .. +/usr/bin/install -m 644 test/*.* $RPM_BUILD_ROOT/%{_docdir}/%{name}/test/ +/usr/bin/install -m 644 test/assets/* $RPM_BUILD_ROOT/%{_docdir}/%{name}/test/assets/ +/usr/bin/install -m 644 test/shells/* $RPM_BUILD_ROOT/%{_docdir}/%{name}/test/shells/ %clean rm -rf $RPM_BUILD_ROOT %files %defattr(644,root,root,755) -%doc AUTHORS BUGS ChangeLog doc/ INSTALL_Linux.md INSTALL_macOS.md -%doc INSTALL_Windows.md LICENSE README.md -%doc sdl_bgi.spec test/ TODO VERSION +%doc AUTHORS BUGS ChangeLog INSTALL_Emscripten.md +%doc INSTALL_Linux.md INSTALL_Windows.md INSTALL_macOS.md +%doc LICENSE README.md sdl_bgi.spec TODO VERSION %attr(644,root,root) %{_libdir}/lib%{name}.so %attr(644,root,root) %{_includedir}/SDL2/SDL_bgi.h %attr(644,root,root) %{_includedir}/graphics.h %attr(644,root,root) %{_mandir}/man3/graphics.3.gz +%attr(644,root,root) %{_docdir}/%{name}/test/* + %changelog +* Sat May 28 2022 Guido Gonzato +Improved document section. + * Tue Jan 2 2018 Guido Gonzato Slightly improved portability. diff --git a/src/Makefile b/src/Makefile index a14c992..e6fe2bc 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,6 @@ # Makefile for SDL_bgi -# For GNU/Linux, macOS, and MSYS2 + Mingw +# For GNU/Linux, macOS, and MSYS2 + MinGW-64 +# Latest update: May 28, 2022 VERSION := $(shell cat ../VERSION) NAME = SDL_bgi @@ -40,7 +41,8 @@ endif # MSYS2 msys := $(findstring _NT, $(PLATFORM)) ifeq ($(msys),_NT) -PLATFORM = MSYS +PLATFORM = MSYS2 +# use native MinGW-64 SDL2 packages INC_DIR = /mingw64/include SDL_INC = $(INC_DIR)/SDL2 LIB_DIR = /mingw64/bin @@ -53,8 +55,12 @@ endif $(info *** Building on $(PLATFORM) ***) $(info ) -# C compiler: tested with gcc and clang +# C compiler: tested with gcc, clang, and tcc +# tcc is supported on GNU/Linux only +# CC = tcc -D SDL_DISABLE_IMMINTRIN_H CC = gcc +# if you experience keyboard bugs on MSYS2: +# CC = gcc -DMINGW_BUG # -Wextra CFLAGS = -O2 -std=gnu99 -g -c -Wall \ -I $(INC_DIR) -I $(SDL_INC) $(PIC) @@ -69,18 +75,40 @@ $(LIB): $(OBJ) $(CC) -shared -o $(LIB) $(OBJ) $(LDFLAGS) ; \ $(STRIP) $(LIB) +ifdef EMSDK + +EMINCLUDE=$(EMSDK)/upstream/emscripten/cache/sysroot/include +EMLIB=$(EMSDK)/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten + +wasm: # tested on GNU/Linux only! + emcc -std=gnu99 -O2 -Wall $(SRC) \ + -s USE_SDL=2 -c -o $(NAME).bc ; \ + emar rcs lib$(NAME).a $(NAME).bc ; \ + /usr/bin/install -m 644 $(HEADER2) $(EMINCLUDE) ; \ + /usr/bin/install -m 644 $(HEADER1) $(EMINCLUDE)/SDL2 ; \ + /usr/bin/install -m 644 lib$(NAME).a $(EMLIB) +unwasm: + /bin/rm -f $(EMINCLUDE)/$(HEADER2) ; \ + /bin/rm -f $(EMINCLUDE)/SDL2/$(HEADER1) ; \ + /bin/rm -f $(EMLIB)/lib$(NAME).a + +endif + install: $(LIB) $(HEADER1) - install -m 755 $(LIB) $(LIB_DIR) ; \ - install -m 644 $(HEADER1) $(SDL_INC) ; \ - install $(HEADER2) $(INC_DIR) + /usr/bin/install -m 755 $(LIB) $(LIB_DIR) ; \ + /usr/bin/install -m 644 $(HEADER1) $(SDL_INC) ; \ + /usr/bin/install $(HEADER2) $(INC_DIR) uninstall: - rm -f $(SDL_INC)/$(HEADER1) ; \ - rm -f $(INC_DIR)/$(HEADER2) - rm -f $(LIB_DIR)/$(LIB) + /bin/rm -f $(SDL_INC)/$(HEADER1) ; \ + /bin/rm -f $(INC_DIR)/$(HEADER2) ; \ + /bin/rm -f $(LIB_DIR)/$(LIB) test: all cd ../test; make clean: - rm -f $(OBJ) $(LIB) a.out + /bin/rm -f $(OBJ) $(LIB) a.out *.bc *.a *~ + + +# --- end of Makefile diff --git a/src/Makefile.CodeBlocks b/src/Makefile.CodeBlocks index 031ee3b..e553eaf 100644 --- a/src/Makefile.CodeBlocks +++ b/src/Makefile.CodeBlocks @@ -1,5 +1,5 @@ # Makefile for SDL_bgi, for CodeBlocks + Mingw 20.03 -# and SDL2 2.0.16 +# and SDL2 2.0.22 # To compile SDL_bgi for CodeBlocks from the # MSYS2 shell, run this command: @@ -13,8 +13,8 @@ HEADER1 = SDL_bgi.h HEADER2 = graphics.h # We assume that CodeBlocks is installed in C:\CodeBlocks, -# while SDL2 is installed in C:\SDL2-2.0.16 -SDL_DIR = /c/SDL2-2.0.16 +# while SDL2 is installed in C:\SDL2-2.0.22 +SDL_DIR = /c/SDL2-2.0.22 INC_DIR = /c/CodeBlocks/MinGW/include/ SDL_INC = $(SDL_DIR)/x86_64-w64-mingw32/include/ SDL_LIB = $(SDL_DIR)/x86_64-w64-mingw32/lib/ diff --git a/src/Makefile.DevCpp b/src/Makefile.DevCpp index aea6bd2..7c7ed05 100644 --- a/src/Makefile.DevCpp +++ b/src/Makefile.DevCpp @@ -1,5 +1,5 @@ # Makefile for SDL_bgi, for Dev-C++ 5.11, TDM-GCC 5.1.0-3, -# and SDL2 2.0.16 +# and SDL2 2.0.22 # To compile SDL_bgi for DevCpp from the # MSYS2 shell, run this command: @@ -12,8 +12,8 @@ OBJ = $(NAME).o HEADERS = SDL_bgi.h # We assume that Dev-Cpp is installed in C:\Dev-Cpp, -# while SDL2 is installed in C:\SDL2-2.0.16 -SDL_DIR = /c/SDL2-2.0.16 +# while SDL2 is installed in C:\SDL2-2.0.22 +SDL_DIR = /c/SDL2-2.0.22 INC_DIR = /c/Dev-Cpp/MinGW64/include/ SDL_INC = $(SDL_DIR)/x86_64-w64-mingw32/include/ SDL_LIB = $(SDL_DIR)/x86_64-w64-mingw32/lib/ diff --git a/src/SDL_bgi.c b/src/SDL_bgi.c index 17a9fde..1d8575a 100644 --- a/src/SDL_bgi.c +++ b/src/SDL_bgi.c @@ -7,13 +7,13 @@ // By Guido Gonzato, PhD // Automatic refresh patch, CHR font support: // Marco Diego Aurélio Mesquita -// Latest update: September 16, 2021 +// Latest update: May 28, 2022 // ZLib License /* -Copyright (c) 2014-2021 Guido Gonzato, PhD +Copyright (c) 2014-2022 Guido Gonzato, PhD This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -51,19 +51,26 @@ freely, subject to the following restrictions: // stuff gets drawn here; these variables are available to the // programmer. All the rest is hidden. -SDL_Window *bgi_window; -SDL_Renderer *bgi_renderer; -SDL_Texture *bgi_texture; +SDL_Window + *bgi_window; +SDL_Renderer + *bgi_renderer; +SDL_Texture + *bgi_texture; // ARGB palette initial size; it can be resized using resizepalette(). -Uint32 PALETTE_SIZE = 4096; +Uint32 + PALETTE_SIZE = 4096; // static global variables. I am not afraid of global variables. -static SDL_Window *bgi_win[NUM_BGI_WIN]; -static SDL_Renderer *bgi_rnd[NUM_BGI_WIN]; -static SDL_Texture *bgi_txt[NUM_BGI_WIN]; +static SDL_Window + *bgi_win[NUM_BGI_WIN]; +static SDL_Renderer + *bgi_rnd[NUM_BGI_WIN]; +static SDL_Texture + *bgi_txt[NUM_BGI_WIN]; // multiple windows @@ -84,8 +91,9 @@ static SDL_Surface // pixel data of active and visual pages static Uint32 - *bgi_activepage[NUM_BGI_WIN], // active (= being drawn on) page; + *bgi_activepage[NUM_BGI_WIN]; // active (= being drawn on) page; // may be hidden +static Uint32 *bgi_visualpage[NUM_BGI_WIN]; // visualised page // This is how we draw stuff on the screen. Pixels pointed to by @@ -103,7 +111,8 @@ static Uint32 // this is the global palette, containing all colours: // size is BGI_COLORS + TMP_COLORS + PALETTE_SIZE -static Uint32 *bgi_argb_palette; +static Uint32 + *bgi_argb_palette; // default 16-colour palette; values can't be changed. // RGB colour definitions are taken from https://www.colorhexa.com/ @@ -189,7 +198,7 @@ static int bgi_refresh_rate = 0, // window refresh rate bgi_error_code = grNoInitGraph, // graphics error code - bgi_last_key_pressed, // last key pressed + bgi_last_key_pressed = 0, // last key pressed bgi_internal_font_height, // font height bgi_internal_offset, // offset for outtextxy() bgi_internal_font_desc; @@ -220,14 +229,19 @@ static float // mouse structure struct { - int x; // coordinates of last mouse click + int x; // coordinates of last mouse click int y; - Uint8 btn; // button clicked + Uint8 btn; // button clicked + int clicks; // -1=release, 0=no click, 1 or 2 = single or double click + int wheel; // 1=away from user, -1=towards the user } bgi_mouse; -// mutex for update timer/thread +// mutex for update timer/thread; not available in emscripten + +#ifndef __EMSCRIPTEN__ static SDL_mutex *bgi_update_mutex = NULL; +#endif // BGI window title static char @@ -560,6 +574,8 @@ static void refresh_window (void); // Let's start! +// ----- + // Error handling static void check_initgraph () @@ -984,11 +1000,13 @@ void arc (int x, int y, int stangle, int endangle, int radius) // Draws a circular arc centered at (x, y), with a radius // given by radius, traveling from stangle to endangle. - // Quick and dirty for now, Bresenham-based later (maybe) + // Quick and dirty for now; maybe a faster implementation later, + // http://www.realitypixels.com/turk/computergraphics/CircularArcSubdivision.pdf check_initgraph (); - int angle; + int + angle; if (0 == radius) return; @@ -1023,8 +1041,7 @@ void bar (int left, int top, int right, int bottom) check_initgraph (); int - y, - tmp, tmpcolor, tmpthickness; + y, tmp, tmpcolor, tmpthickness; tmp = bgi_fg_color; @@ -1061,7 +1078,8 @@ void bar3d (int left, int top, int right, check_initgraph (); - Uint32 tmp, tmpcolor; + Uint32 + tmp, tmpcolor; swap_if_greater (&left, &right); swap_if_greater (&top, &bottom); @@ -1151,7 +1169,8 @@ void cleardevice (void) check_initgraph (); - int x, y; + int + x, y; bgi_cp_x = bgi_cp_y = 0; @@ -1172,7 +1191,8 @@ void clearviewport (void) check_initgraph (); - int x, y; + int + x, y; bgi_cp_x = bgi_cp_y = 0; @@ -1192,6 +1212,12 @@ void closegraph (void) check_initgraph (); +#ifdef __EMSCRIPTEN__ + // for Emscripten output + cleardevice (); + refresh (); +#endif + // waits for update callback to finish bgi_refresh_needed = SDL_FALSE; @@ -1210,7 +1236,9 @@ void closegraph (void) // for (int page = 0; page < bgi_np; page++) // SDL_FreeSurface (bgi_vpage[page]); +#ifndef __EMSCRIPTEN__ SDL_UnlockMutex (bgi_update_mutex); +#endif // Destroy our loaded fonts for (int i = 0; i < MAX_FONTS; i++) @@ -1219,10 +1247,14 @@ void closegraph (void) // Only calls SDL_Quit if not running fullscreen if (SDL_FULLSCREEN != bgi_gm) SDL_Quit (); - + // the program might continue in text mode bgi_num_windows = 0; +#ifdef __EMSCRIPTEN__ + emscripten_run_script ("window.close()"); +#endif + } // closegraph () // ----- @@ -1239,13 +1271,12 @@ void delay (int msec) do { - if (event()) + if (event ()) ; // event recorded } while (SDL_GetTicks () < stop); -} // edelay () - +} // delay () // ----- @@ -1267,7 +1298,8 @@ void drawpoly (int numpoints, int *polypoints) check_initgraph (); - int n; + int + n; for (n = 0; n < numpoints - 1; n++) line_fast (polypoints[2*n], polypoints[2*n + 1], @@ -1284,7 +1316,8 @@ void drawpoly (int numpoints, int *polypoints) static void swap_if_greater (int *x1, int *x2) { - int tmp; + int + tmp; if (*x1 > *x2) { tmp = *x1; @@ -1307,7 +1340,8 @@ void ellipse (int x, int y, int stangle, int endangle, check_initgraph (); - int angle; + int + angle; if (0 == xradius && 0 == yradius) return; @@ -1649,10 +1683,10 @@ static void ff_putpixel (int x, int y) Uint8 ptn; - + x += vp.left; y += vp.top; - + ptn = mirror_bits (fill_patterns[bgi_fill_style.pattern][y % 8]); // if the corresponding bit in the pattern is 1 @@ -1674,19 +1708,19 @@ void _floodfill (int x, int y, int border) x1, sl_x1, sl_x2, // scanline X coordinates oldcol = getpixel (x, y); - + // draw current scanline from start position to the right x1 = x; while (x1 < getmaxx () && getpixel (x1, y) != border) ff_putpixel (x1++, y); sl_x2 = x1 - 1; // scanline right X coordinate - + // draw current scanline from start position to the left x1 = x - 1; while (x1 >= 0 && getpixel (x1, y) != border) ff_putpixel (x1--, y); sl_x1 = x1 + 1; // scanline left X coordinate - + // test for new scanlines above x1 = x; while (x1 < getmaxx () && x1 <= sl_x2) { @@ -1700,7 +1734,7 @@ void _floodfill (int x, int y, int border) _floodfill (x1, y - 1, border); x1--; } - + // test for new scanlines below x1 = x; while (x1 < getmaxx () && x1 <= sl_x2) { @@ -1708,14 +1742,14 @@ void _floodfill (int x, int y, int border) _floodfill (x1, y + 1, border); x1++; } - + x1 = x - 1; while (x1 >= 0 && x1 >= sl_x1) { if (y < getmaxy () - 1 && getpixel (x1, y + 1) == oldcol) _floodfill (x1, y + 1, border); x1--; } - + } // _floodfill () // ----- @@ -1749,30 +1783,30 @@ void floodfill (int x, int y, int border) _floodfill (x, y, border); return; } - + else { // fill patterns - + if (bgi_bg_color == oldcol) { - + // solid fill first, then pattern fill on top of it tmp_pattern = bgi_fill_style.pattern; bgi_fill_style.pattern = SOLID_FILL; tmp_color = bgi_fill_style.color; - + // find a suitable temporary fill colour; it must be // different from the border, the background, // and the former fill colour for (int i = BLACK; i < MAXCOLORS + 1; i++) { bgi_fill_style.color = i; - if (oldcol != bgi_fill_style.color && + if (oldcol != bgi_fill_style.color && border != bgi_fill_style.color && tmp_color != bgi_fill_style.color) break; } - + // solid fill... _floodfill (x, y, border); - + // ...then pattern fill bgi_fill_style.pattern = tmp_pattern; bgi_fill_style.color = tmp_color; @@ -1844,9 +1878,9 @@ int getbkcolor (void) // ----- -// this function should be simply named "getch", but this name -// causes a bug in MSYS2. -// "getch" is defined as a macro in SDL_bgi.h +// This function should be simply named "getch()", but this name +// causes a bug in MSYS2 (already defined in curses.h and elsewere) +// "getch" is therefore defined as a macro in SDL_bgi.h // **Note**: this function belongs to "conio.h"; it is here // for convenience and WinBGIm compatibility. @@ -1859,20 +1893,25 @@ int bgi_getch (void) int key, type; + SDL_Keymod + keymod; + refresh (); if (bgi_window_is_hidden) return (getchar ()); - // any pending keypresses by kbhit()? + // any pending keypresses by kbhit ()? if (SDL_TRUE == bgi_key_pressed) { bgi_key_pressed = SDL_FALSE; return bgi_last_key_pressed; } do { + key = getevent (); - type = eventtype (); + type = bgi_last_event; + keymod = SDL_GetModState (); if (QUIT == type) return QUIT; @@ -1888,8 +1927,14 @@ int bgi_getch (void) key != KEY_LGUI && key != KEY_RGUI && key != KEY_MENU && - key != KEY_ALT_GR) // can't catch AltGr! + key != KEY_ALT_GR) { // can't catch AltGr! + if (KMOD_LSHIFT == keymod || + KMOD_RSHIFT == keymod || + KMOD_CAPS == keymod) + key -= ('a' - 'A'); return (int) key; + } + } while (1); // we should never get here... @@ -1983,8 +2028,10 @@ void getimage (int left, int top, int right, int bottom, void *bitmap) check_initgraph (); - Uint32 bitmap_w, bitmap_h, *tmp; - int i = 2, x, y; + Uint32 + bitmap_w, bitmap_h, *tmp; + int + i = 2, x, y; // bitmap has already been malloc()'ed by the user. tmp = bitmap; @@ -2038,12 +2085,13 @@ int getmaxheight (void) { // Returns the maximum height available for a new window. - int x, y; - + int + x, y; + getscreensize (&x, &y); - + return (y); - + } // getmaxheight () // ----- @@ -2062,12 +2110,13 @@ int getmaxwidth (void) { // Returns the maximum width available for a new window. - int x, y; - + int + x, y; + getscreensize (&x, &y); - + return (x); - + } // getmaxwidth () // ----- @@ -2189,7 +2238,7 @@ void getpalette (struct palettetype *palette) for (int i = BLACK; i < MAXCOLORS; i++) palette->colors[i] = bgi_argb_palette[i]; - + palette->size = MAXCOLORS + 1; } // getpalette () @@ -2237,8 +2286,10 @@ unsigned int getpixel (int x, int y) check_initgraph (); - int col; - Uint32 tmp; + int + col; + Uint32 + tmp; x += vp.left; y += vp.top; @@ -2340,27 +2391,28 @@ char *grapherrormsg (int errorcode) // CHECK // check_initgraph (); - char *error_msg[] = { - "No error", - "(BGI) graphics not installed (use initgraph)", - "Graphics hardware not detected", - "Device driver file not found", - "Invalid device driver file", - "Not enough memory to load driver", - "Out of memory in scan fill", - "Out of memory in flood fill", - "Font file not found", - "Not enough memory to load font", - "Invalid graphics mode for selected driver", - "Graphics error", - "Graphics I/O error", - "Invalid font file", - "Invalid font number", - "Invalid device number", - "", // -16, unspecified - "", // -17, unspecified - "Invalid version number" - }; + char + *error_msg[] = { + "No error", + "(BGI) graphics not installed (use initgraph)", + "Graphics hardware not detected", + "Device driver file not found", + "Invalid device driver file", + "Not enough memory to load driver", + "Out of memory in scan fill", + "Out of memory in flood fill", + "Font file not found", + "Not enough memory to load font", + "Invalid graphics mode for selected driver", + "Graphics error", + "Graphics I/O error", + "Invalid font file", + "Invalid font number", + "Invalid device number", + "", // -16, unspecified + "", // -17, unspecified + "Invalid version number" + }; return error_msg [-bgi_error_code]; @@ -2416,7 +2468,7 @@ void graphdefaults (void) // use the new palette for (int i = BLACK; i < WHITE + 1; i++) bgi_pal.colors[i] = bgi_std_palette[i]; - + // the rgb palette is not initialised } // graphdefaults () @@ -2479,6 +2531,22 @@ void initgraph (int *graphdriver, int *graphmode, char *pathtodriver) } } +#ifdef __EMSCRIPTEN__ + if (NULL != graphdriver && DETECT == *graphdriver) { + // graphics mode can be forced to VGA for compatibility + char res[4]; + FILE *file = fopen ("SDL_BGI_RES", "r"); + if (NULL != file) { + fgets (res, 4, file); + fclose (file); + if (0 == strcmp ("VGA", res)) + bgi_gm = SDL_VGA; + if (NULL != graphmode) + *graphmode = SDL_VGA; + } + } +#endif + switch (bgi_gm) { case SDL_320x200: @@ -2547,12 +2615,23 @@ void initpalette (void) check_initgraph (); +#ifndef __EMSCRIPTEN__ char *res = getenv ("SDL_BGI_PALETTE"); if (NULL != res && (0 == strcmp ("BGI", res)) ) bgi_use_newpalette = SDL_FALSE; +#else + char res[4]; + FILE *file = fopen ("SDL_BGI_PALETTE", "r"); + if (NULL != file) { + fgets (res, 4, file); + fclose (file); + if (0 == strcmp ("BGI", res)) + bgi_use_newpalette = SDL_FALSE; + } +#endif bgi_argb_palette = calloc (BGI_COLORS + TMP_COLORS + PALETTE_SIZE, sizeof (Uint32)); @@ -2562,7 +2641,7 @@ void initpalette (void) showerrorbox (str); exit (1); } - + if (SDL_FALSE == bgi_use_newpalette) // use the old (ugly) palette for (int i = BLACK; i < WHITE + 1; i++) bgi_argb_palette[i] = bgi_orig_palette[i]; @@ -2574,27 +2653,33 @@ void initpalette (void) // ----- -// this function should be simply named "kbhit", but this name -// causes a bug in MSYS2. -// "kbhit" is defined as a macro in SDL_bgi.h +// 1. This function should be simply named "kbhit()", but this name +// clashes with a function in MSYS2/Mingw64. "kbhit" is therefore +// defined as a macro in SDL_bgi.h -// **Note**: this function belongs to "conio.h"; it is here -// for convenience and WinBGIm compatibility. +// 2. **Note**: this function belongs to "conio.h"; it is here for +// convenience and WinBGIm compatibility. int bgi_kbhit (void) { // Returns 1 when a key is pressed, or QUIT // if the user asked to close the window - SDL_Event event; - SDL_Keycode key; + SDL_Event + event; + SDL_Keycode + key; + SDL_Keymod + keymod; update (); if (SDL_PollEvent (&event)) { - + if (SDL_KEYDOWN == event.type) { key = event.key.keysym.sym; + bgi_last_event = event.type; + keymod = SDL_GetModState (); if (key != SDLK_LCTRL && key != SDLK_RCTRL && key != SDLK_LSHIFT && @@ -2610,6 +2695,10 @@ int bgi_kbhit (void) key != SDLK_APPLICATION) { bgi_key_pressed = SDL_TRUE; bgi_last_key_pressed = (int) key; + if (KMOD_LSHIFT == keymod || + KMOD_RSHIFT == keymod || + KMOD_CAPS == keymod) + bgi_last_key_pressed -= ('a' - 'A'); return SDL_TRUE; } else @@ -2622,7 +2711,7 @@ int bgi_kbhit (void) } else SDL_PushEvent (&event); // don't disrupt the mouse - + } // if (SDL_PollEvent (&event)) return SDL_FALSE; @@ -2631,6 +2720,15 @@ int bgi_kbhit (void) // ----- +int lastkey (void) +{ + // Returns the last key pressed + + return bgi_last_key_pressed; +} + +// ----- + // Bresenham's line algorithm routines that implement logical // operations: copy, xor, and, or, not. @@ -2892,7 +2990,8 @@ void line (int x1, int y1, int x2, int y2) check_initgraph (); - int oct; + int + oct; check_initgraph (); @@ -3104,7 +3203,8 @@ static void _bar (int left, int top, int right, int bottom) { // Used by drawchar_bitmap() - int tmp, y; + int + tmp, y; // like bar (), but uses bgi_fg_color @@ -3182,7 +3282,7 @@ static void drawchar_internal (int ch) num; // TODO: char -> short int? - + const char *glyph; @@ -3341,7 +3441,7 @@ void outtextxy (int x, int y, char *textstring) return; th = textheight (textstring); - + if (HORIZ_DIR == bgi_txt_style.direction) { if (LEFT_TEXT == bgi_txt_style.horiz) @@ -3407,7 +3507,7 @@ void outtextxy (int x, int y, char *textstring) bgi_line_style.linestyle = tmp_stl; bgi_cp_x = tmp_x; bgi_cp_y = tmp_y; - + update (); } // outtextxy () @@ -3423,7 +3523,8 @@ void pieslice (int x, int y, int stangle, int endangle, int radius) check_initgraph (); - int angle; + int + angle; if (0 == radius || stangle == endangle) return; @@ -3450,7 +3551,7 @@ void pieslice (int x, int y, int stangle, int endangle, int radius) line_fast (x, y, bgi_last_arc.xend, bgi_last_arc.yend); angle = (stangle + endangle) / 2; - + // !!! FIXME: what if we're trying to fill an already filled pieslice? floodfill (x + (radius * cos (angle * PI_CONV)) / 2, y - (radius * sin (angle * PI_CONV)) / 2, @@ -3615,8 +3716,9 @@ static void putpixel_not (int x, int y, Uint32 pixel) void putpixel (int x, int y, int color) { // Plots a point at (x,y) in the color defined by 'color'. - - int tmpcolor; + + int + tmpcolor; check_initgraph (); @@ -3726,7 +3828,8 @@ void sector (int x, int y, int stangle, int endangle, check_initgraph (); - int angle, tmpcolor; + int + angle, tmpcolor; if (0 == xradius && 0 == yradius) return; @@ -3788,7 +3891,7 @@ void setallpalette (struct palettetype *palette) // Sets the current palette to the values given in palette. check_initgraph (); - + if (NULL == palette) { bgi_error_code = grError; return; @@ -3820,7 +3923,7 @@ void setbkcolor (int col) if (col < -1) col += 32768; - + // COLOR () or COLOR32 () or RGBPALETTE () set ARGB_BG_COL if (-1 == col) { bgi_bg_color = ARGB_BG_COL; @@ -3832,7 +3935,7 @@ void setbkcolor (int col) bgi_argb_mode = SDL_FALSE; bgi_bg_color = col; } - + // this was undocumented! clearviewport (); @@ -3848,7 +3951,7 @@ void _setcolor (int col) if (col < -1) col += 32768; - + // COLOR () or COLOR32 () or RGBPALETTE () set ARGB_FG_COL if (-1 == col) { bgi_fg_color = ARGB_FG_COL; @@ -3875,7 +3978,7 @@ void setcolor (int col) if (col < -1) col += 32768; - + // COLOR () or COLOR32 () or RGBPALETTE () set ARGB_FG_COL if (-1 == col) { bgi_fg_color = ARGB_FG_COL; @@ -3899,7 +4002,7 @@ void setfillpattern (char *upattern, int color) // Sets a user-defined fill pattern. check_initgraph (); - + if (color < -1) color += 32768; @@ -3935,7 +4038,7 @@ void setfillstyle (int pattern, int color) bgi_error_code = grError; return; } - + // if (color < -1) // color += 32768; @@ -3963,7 +4066,7 @@ void setgraphmode (int mode) // Shows the window that was hidden by restorecrtmode (). check_initgraph (); - + SDL_ShowWindow (bgi_win[bgi_current_window]); bgi_window_is_hidden = SDL_FALSE; cleardevice (); @@ -3994,18 +4097,18 @@ void setpalette (int colornum, int color) int x, y; - + Uint32 oldcol, newcol; - + check_initgraph (); // handle negative colours? if (colornum == color || color < -1 || colornum < -1) return; - + oldcol = bgi_argb_palette[colornum]; - + if (-1 == color) // user called COLOR() bgi_argb_palette[colornum] = bgi_argb_palette[ARGB_TMP_COL]; else { @@ -4023,7 +4126,7 @@ void setpalette (int colornum, int color) for (y = 0; y < getmaxy (); y++) if (oldcol == PIXEL (x, y)) PIXEL (x, y) = newcol; - + } // setpalette () // ----- @@ -4164,7 +4267,7 @@ void settextstyle (int font, int direction, int charsize) // undocumented feature; please see installuserfont() if (LAST_SPEC_FONT == font && NULL == chr_font) bgi_font = DEFAULT_FONT; - + if (font > LAST_SPEC_FONT) { // use a loaded .CHR font chr_font = chr_fonts[font]; if (NULL == chr_font) { @@ -4216,12 +4319,12 @@ void setusercharsize (int multx, int divx, int multy, int divy) bgi_user_size_y = (float)multy / (float)divy; // According to the docs: - // "When charsize equals 0, the output functions outtext and + // "When charsize equals 0, the output functions outtext and // outtextxy magnify the stroked font text using either the default // character magnification factor (4) or the user-defined character // size given by setusercharsize." // But Turbo C++ 1.01 always uses magnification. - // + // // if (USER_CHAR_SIZE == bgi_txt_style.charsize) { bgi_font_mag_x = bgi_user_size_x; bgi_font_mag_y = bgi_user_size_y; @@ -4293,7 +4396,7 @@ int textheight (char *textstring) height; // FIXME: take care of loaded fonts. - + if (DEFAULT_FONT == bgi_font) height = bgi_font_mag_y * bgi_bitmap_font_height; else @@ -4311,8 +4414,10 @@ int textwidth (char *textstring) check_initgraph (); - int ch; - float width = 0.0; + int + ch; + float + width = 0.0; if (DEFAULT_FONT == bgi_font) // 8x8 bitmap font width = (strlen (textstring) * @@ -4441,7 +4546,7 @@ int RGBPALETTE (int color) // to set an ARGB color. bgi_use_tmp_color = SDL_TRUE; - bgi_argb_palette[ARGB_TMP_COL] = + bgi_argb_palette[ARGB_TMP_COL] = bgi_argb_palette[BGI_COLORS + TMP_COLORS + color]; return -1; @@ -4494,7 +4599,7 @@ void closewindow (int id) // Closes a window. check_initgraph (); - + if (SDL_FALSE == bgi_active_windows[id]) { char str[40]; sprintf (str, "Window %d does not exist.\n", id); @@ -4513,6 +4618,20 @@ void closewindow (int id) // ----- +int doubleclick (void) +{ + + if (2 == bgi_mouse.clicks) { + bgi_mouse.clicks = 0; + return SDL_TRUE; + } + else + return SDL_FALSE; + +} // doubleclick () + +// ----- + int edelay (int msec) { // Waits for 'msec' milliseconds and returns SDL_FALSE if no @@ -4528,7 +4647,7 @@ int edelay (int msec) do { - if (event()) + if (event ()) ev = SDL_TRUE; } while (SDL_GetTicks () < stop); @@ -4541,21 +4660,66 @@ int edelay (int msec) int event (void) { - // Returns SDL_TRUE if an event has occurred. + // Returns SDL_TRUE if an event has occurred, SDL_FALSE otherwise. - SDL_Event event; - update (); + SDL_Event + event; + update (); + if (SDL_PollEvent (&event)) { - if ( (SDL_KEYDOWN == event.type) || - (SDL_MOUSEBUTTONDOWN == event.type) || - (SDL_MOUSEWHEEL == event.type) || - (SDL_QUIT == event.type) ) { - SDL_PushEvent (&event); // don't disrupt the event - bgi_last_event = event.type; + + bgi_last_event = event.type; + + switch (bgi_last_event) { + + // no SDL_WINDOWEVENT here + + case SDL_KEYDOWN: + bgi_last_key_pressed = (int) event.key.keysym.sym; + SDL_PushEvent (&event); // don't disrupt the keyboard + bgi_mouse.x = bgi_mouse.y = -1; return SDL_TRUE; - } - } + break; + + case SDL_MOUSEMOTION: + bgi_mouse.x = event.motion.x; + bgi_mouse.y = event.motion.y; + bgi_last_key_pressed = -1; + return SDL_TRUE; + + case SDL_MOUSEBUTTONDOWN: + bgi_mouse.btn = event.button.button; + bgi_mouse.clicks = event.button.clicks; + SDL_GetMouseState (&bgi_mouse.x, &bgi_mouse.y); + return SDL_TRUE; + break; + + case SDL_MOUSEBUTTONUP: + bgi_mouse.btn = event.button.button; + bgi_mouse.clicks = 0; + SDL_GetMouseState (&bgi_mouse.x, &bgi_mouse.y); + return SDL_TRUE; + break; + + case SDL_MOUSEWHEEL: + bgi_mouse.wheel = (event.wheel.y > 0) ? + WM_WHEELUP : WM_WHEELDOWN; + SDL_GetMouseState (&bgi_mouse.x, &bgi_mouse.y); + return SDL_TRUE; + break; + + case SDL_QUIT: + return SDL_TRUE; + break; + + default: + ; + + } // switch + + } // if + return SDL_FALSE; } // event () @@ -4564,7 +4728,9 @@ int event (void) int eventtype (void) { - // Returns the type of event occurred + // Returns the type of the last event: + // SDL_KEYDOWN, SDL_MOUSEMOTION, SDL_MOUSEBUTTONDOWN, + // SDL_MOUSEBUTTONUP, SDL_MOUSEWHEEL, SDL_QUIT return (bgi_last_event); @@ -4585,6 +4751,26 @@ void getbuffer (Uint32 *buffer) // ----- +int getclick () +{ + // Waits for a button click. + + int + click; + + while (1) { + + click = mouseclick (); + if (WM_LBUTTONDOWN == click || + WM_MBUTTONDOWN == click || + WM_RBUTTONDOWN == click) + return bgi_mouse.btn; + } + +} // getclick () + +// ----- + int getcurrentwindow (void) { // Returns the ID of current window @@ -4597,82 +4783,119 @@ int getcurrentwindow (void) int getevent (void) { - // Waits for a keypress or mouse click, and returns the code of - // the mouse button or key that was pressed. + // Waits for a keypress or mouse click, and returns + // the code of the mouse event or key that was pressed. - SDL_Event event; + SDL_Event + event; - // wait for an event - while (1) { + while (SDL_WaitEvent (&event)) { - while (SDL_WaitEvent (&event)) + bgi_last_event = event.type; - switch (event.type) { + switch (bgi_last_event) { - case SDL_WINDOWEVENT: + case SDL_WINDOWEVENT: - switch (event.window.event) { + switch (event.window.event) { - case SDL_WINDOWEVENT_SHOWN: - case SDL_WINDOWEVENT_EXPOSED: - refresh_window (); - break; + case SDL_WINDOWEVENT_SHOWN: + case SDL_WINDOWEVENT_EXPOSED: + refresh_window (); + break; - case SDL_WINDOWEVENT_CLOSE: - bgi_last_event = QUIT; - return QUIT; - break; + case SDL_WINDOWEVENT_CLOSE: + bgi_last_event = QUIT; + return SDL_QUIT; + break; - default: - ; + default: + ; - } // switch (event.window.event) + } // switch (event.window.event) + break; - break; +#if 0 + case SDL_MOUSEMOTION: + SDL_GetMouseState (&bgi_mouse.x, &bgi_mouse.y); + return SDL_MOUSEMOTION; + break; +#endif - case SDL_KEYDOWN: - bgi_last_event = SDL_KEYDOWN; - bgi_mouse.x = bgi_mouse.y = -1; - return event.key.keysym.sym; - break; + case SDL_KEYDOWN: + bgi_last_key_pressed = (int) event.key.keysym.sym; + bgi_mouse.x = bgi_mouse.y = -1; + // logically, it should be SDL_KEYDOWN + return bgi_last_key_pressed; + break; - case SDL_MOUSEBUTTONDOWN: - bgi_last_event = SDL_MOUSEBUTTONDOWN; - bgi_mouse.x = event.button.x; - bgi_mouse.y = event.button.y; - return event.button.button; - break; + case SDL_MOUSEBUTTONDOWN: + bgi_mouse.btn = event.button.button; + bgi_mouse.clicks = event.button.clicks; + SDL_GetMouseState (&bgi_mouse.x, &bgi_mouse.y); + // logically, it should be SDL_MOUSEBUTTONDOWN + return bgi_mouse.btn; + break; - case SDL_MOUSEWHEEL: - bgi_last_event = SDL_MOUSEWHEEL; - SDL_GetMouseState (&bgi_mouse.x, &bgi_mouse.y); - if (1 == event.wheel.y) // up - return (WM_WHEELUP); - else - return (WM_WHEELDOWN); - break; + case SDL_MOUSEWHEEL: + SDL_GetMouseState (&bgi_mouse.x, &bgi_mouse.y); + return (event.wheel.y > 0) ? + WM_WHEELUP : WM_WHEELDOWN; + break; - default: - ; + default: + ; - } // switch (event.type) + } // switch (bgi_last_event) - } // while (1) + } // while + + return 0; } // getevent () // ----- -void getleftclick (void) +static void _getclick (int btn) { - // Waits for a left button click + release. + // Waits for the specified 'btn' click. + + // temporary slow mode - I don't know why + // Emscripten wants this in order to work - while (!ismouseclick (WM_LBUTTONDOWN)) - ; - while (ismouseclick (WM_LBUTTONDOWN)) - ; + int + tmp = bgi_fast_mode; + bgi_fast_mode = SDL_FALSE; + + SDL_PumpEvents (); + + // click + while (1) { + event (); + if (SDL_MOUSEBUTTONDOWN == bgi_last_event && + bgi_mouse.btn == btn) + break; + } + + // release + while (1) { + event (); + if (SDL_MOUSEBUTTONUP == bgi_last_event) + break; + } + + bgi_fast_mode = tmp; + +} // _getclick () + +// ----- + +void getleftclick (void) +{ -} // getleftclickk () + _getclick (WM_LBUTTONDOWN); + +} // getleftclick () // ----- @@ -4693,19 +4916,16 @@ void getlinebuffer (int y, Uint32 *linebuffer) void getmiddleclick (void) { // Waits for a middle button click + release. - - while (!ismouseclick (WM_MBUTTONDOWN)) - ; - while (ismouseclick (WM_MBUTTONDOWN)) - ; - -} // getmiddleclick () + + _getclick (WM_MBUTTONDOWN); + +} // getleftclick () // ----- void getmouseclick (int kind, int *x, int *y) { - // Sets the x,y coordinates of the last 'kind' button click + // Sets the x, y coordinates of the last 'kind' button click // expected by ismouseclick(). if (kind == bgi_mouse.btn) { @@ -4725,14 +4945,14 @@ void getrgbpalette (struct rgbpalettetype *palette, int size) // information about the current RGB palette's size and colors. check_initgraph (); - + if (NULL == palette) return; - + palette->size = size; for (int col = 0; col < size; col++) - palette->colors[col] = + palette->colors[col] = bgi_argb_palette[BGI_COLORS + TMP_COLORS + col]; } // getrgbpalette () @@ -4742,13 +4962,10 @@ void getrgbpalette (struct rgbpalettetype *palette, int size) void getrightclick (void) { // Waits for a right button click + release. - - while (!ismouseclick (WM_RBUTTONDOWN)) - ; - while (ismouseclick (WM_RBUTTONDOWN)) - ; - -} // getrightclick () + + _getclick (WM_RBUTTONDOWN); + +} // getleftclick () // ----- @@ -4764,7 +4981,7 @@ void getscreensize (int *x, int *y) SDL_DisplayMode mode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 }; - + if (SDL_GetDisplayMode (0, 0, &mode) != 0) { SDL_Log ("SDL_GetDisplayMode() failed: %s", SDL_GetError ()); showerrorbox ("SDL_GetDisplayMode() failed"); @@ -4792,10 +5009,17 @@ void initwindow (int width, int height) char str[100]; - + // let's be proactive bgi_error_code = grOk; + // fix wrong values + if (width < 0) + width = 0; + if (height < 0) + height = 0; + +#ifndef __EMSCRIPTEN__ // the mutex is used by update() if (!bgi_update_mutex) bgi_update_mutex = SDL_CreateMutex (); @@ -4810,6 +5034,7 @@ void initwindow (int width, int height) SDL_Log ("SDL_LockMutex() failed: %s", SDL_GetError ()); showerrorbox ("SDL_LockMutex() failed"); } +#endif SDL_DisplayMode mode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 }; @@ -4859,17 +5084,14 @@ void initwindow (int width, int height) return; } - // check if a fullscreen window is already open + // check if a fullscreen window has been created if (SDL_TRUE == fullscreen) { - sprintf (str, "Fullscreen window already open.\n"); + sprintf (str, "Fullscreen window already exists.\n"); fprintf (stderr, "%s", str); showerrorbox (str); return; } - // TODO: what if width or height exceed the screen - // physical dimensions? - // take note of window size bgi_maxx = width - 1; bgi_maxy = height - 1; @@ -4880,6 +5102,7 @@ void initwindow (int width, int height) bgi_maxy = mode.h - 1; bgi_window_flags = bgi_window_flags | SDL_WINDOW_FULLSCREEN_DESKTOP; fullscreen = SDL_TRUE; + bgi_gm = SDL_FULLSCREEN; } else { bgi_maxx = width - 1; @@ -4968,7 +5191,7 @@ void initwindow (int width, int height) graphdefaults (); - // check the environment variable 'SDL_BGI_RATE' + // check for the environment variable 'SDL_BGI_RATE' // and act accordingly char *speed = getenv ("SDL_BGI_RATE"); @@ -4976,7 +5199,6 @@ void initwindow (int width, int height) if (NULL == speed) // variable does not exist speed = "compatible"; else { - if (0 == strcmp ("auto", speed)) sdlbgiauto (); @@ -4988,78 +5210,80 @@ void initwindow (int width, int height) // any other value of SDL_BGI_RATE triggers // "compatible" mode by default +#ifndef __EMSCRIPTEN__ SDL_UnlockMutex (bgi_update_mutex); +#endif // fix fonts magnification - short int default_h[] = + short int default_h[] = {8, 8, 16, 24, 32, 40, 40, 48, 56, 64, 72, 80}; - short int trip_h[] = + short int trip_h[] = {31, 18, 20, 23, 31, 41, 51, 62, 77, 93, 124}; - short int litt_h[] = + short int litt_h[] = {9, 5, 6, 6, 9, 12, 15, 18, 22, 27, 36}; - short int sans_h[] = + short int sans_h[] = {32, 19, 21, 24, 32, 42, 53, 64, 80, 96, 128}; - short int goth_h[] = + short int goth_h[] = {32, 19, 21, 24, 32, 42, 53, 64, 80, 96, 128}; - short int scri_h[] = + short int scri_h[] = {37, 22, 24, 27, 37, 49, 61, 74, 92, 111, 148}; - short int simp_h[] = + short int simp_h[] = {35, 21, 23, 26, 35, 46, 58, 70, 87, 105, 140}; - short int tscr_h[] = + short int tscr_h[] = {31, 18, 20, 23, 31, 41, 51, 62, 77, 93, 124}; - short int lcom_h[] = + short int lcom_h[] = {35, 21, 23, 26, 35, 46, 58, 70, 87, 105, 140}; - short int euro_h[] = + short int euro_h[] = {55, 33, 36, 41, 55, 73, 91, 110, 137, 165, 220}; - short int bold_h[] = + short int bold_h[] = {60, 36, 40, 45, 60, 80, 100, 120, 150, 180, 240}; - + // set font magnification for (int i = 0; i < FONT_SIZES; i++) { - - bgi_font_magnification[DEFAULT_FONT][i] = + + bgi_font_magnification[DEFAULT_FONT][i] = default_h[i] / 8; // bitmap font height - - bgi_font_magnification[TRIPLEX_FONT][i] = + + bgi_font_magnification[TRIPLEX_FONT][i] = (float) trip_h[i] / (float) trip_height; - bgi_font_magnification[SMALL_FONT][i] = + bgi_font_magnification[SMALL_FONT][i] = (float) litt_h[i] / (float) litt_height; - bgi_font_magnification[SANS_SERIF_FONT][i] = + bgi_font_magnification[SANS_SERIF_FONT][i] = (float) sans_h[i] / (float) sans_height; - - bgi_font_magnification[GOTHIC_FONT][i] = + + bgi_font_magnification[GOTHIC_FONT][i] = (float) goth_h[i] / (float) goth_height; - - bgi_font_magnification[SCRIPT_FONT][i] = + + bgi_font_magnification[SCRIPT_FONT][i] = (float) scri_h[i] / (float) scri_height; - - bgi_font_magnification[SIMPLEX_FONT][i] = + + bgi_font_magnification[SIMPLEX_FONT][i] = (float) simp_h[i] / (float) simp_height; - - bgi_font_magnification[TRIPLEX_SCR_FONT][i] = + + bgi_font_magnification[TRIPLEX_SCR_FONT][i] = (float) tscr_h[i] / (float) tscr_height; - - bgi_font_magnification[COMPLEX_FONT][i] = + + bgi_font_magnification[COMPLEX_FONT][i] = (float) lcom_h[i] / (float) lcom_height; - - bgi_font_magnification[EUROPEAN_FONT][i] = + + bgi_font_magnification[EUROPEAN_FONT][i] = (float) euro_h[i] / (float) euro_height; - - bgi_font_magnification[BOLD_FONT][i] = + + bgi_font_magnification[BOLD_FONT][i] = (float) bold_h[i] / (float) bold_height; - - } // for i + } // for i + } // initwindow () // ----- int ismouseclick (int btn) { - // Returns 1 if the 'btn' mouse button was clicked. + // Returns 1 if the 'btn' mouse button is being clicked. SDL_PumpEvents (); @@ -5093,38 +5317,87 @@ int ismouseclick (int btn) int mouseclick (void) { - // Returns the code of the mouse button that was clicked, - // or 0 if none was clicked. - - SDL_Event event; - - while (1) { - - if (SDL_PollEvent (&event)) { + // Returns the code of the current mouse event + // (WM_MOUSEMOVE, WM_LBUTTONDOWN etc.), + // or SDL_FALSE if no mouse event is occurring. - if (SDL_MOUSEBUTTONDOWN == event.type) { - bgi_mouse.x = event.button.x; - bgi_mouse.y = event.button.y; - // double clicks are only available in SDL2 >= 2.0.2 - return (event.button.button); - } - else - if (SDL_MOUSEMOTION == event.type) { - bgi_mouse.x = event.motion.x; - bgi_mouse.y = event.motion.y; - return (WM_MOUSEMOVE); + int + type; + + int + tmp = bgi_fast_mode; + bgi_fast_mode = SDL_FALSE; + + // mouse coords and buttons are set by event () + + if (event ()) { + + type = bgi_last_event; + + switch (type) { + + case SDL_MOUSEBUTTONDOWN: + bgi_fast_mode = tmp; + if (2 == bgi_mouse.clicks) + switch (bgi_mouse.btn) { + case SDL_BUTTON_LEFT: + return WM_LBUTTONDBLCLK; + break; + case SDL_BUTTON_MIDDLE: + return WM_MBUTTONDBLCLK; + break; + case SDL_BUTTON_RIGHT: + return WM_RBUTTONDBLCLK; + break; + } // switch + else // single click + switch (bgi_mouse.btn) { + case SDL_BUTTON_LEFT: + return WM_LBUTTONDOWN; + break; + case SDL_BUTTON_MIDDLE: + return WM_MBUTTONDOWN; + break; + case SDL_BUTTON_RIGHT: + return WM_RBUTTONDOWN; + break; } - else { - SDL_PushEvent (&event); // don't disrupt the keyboard - return SDL_FALSE; - } - return SDL_FALSE; + break; + + case SDL_MOUSEBUTTONUP: + bgi_fast_mode = tmp; + switch (bgi_mouse.btn) { + case SDL_BUTTON_LEFT: + return WM_LBUTTONUP; + break; + case SDL_BUTTON_MIDDLE: + return WM_MBUTTONUP; + break; + case SDL_BUTTON_RIGHT: + return WM_RBUTTONUP; + break; + } // switch + break; + + case SDL_MOUSEMOTION: + bgi_fast_mode = tmp; + return SDL_MOUSEMOTION; + break; - } // if - else - return SDL_FALSE; + case SDL_MOUSEWHEEL: + bgi_fast_mode = tmp; + return bgi_mouse.wheel; + break; + + default: + ; + + } // switch (type) + + } // if event - } // while + bgi_fast_mode = tmp; + return SDL_FALSE; } // mouseclick () @@ -5185,24 +5458,40 @@ void putlinebuffer (int y, Uint32 *linebuffer) // ----- +void copysurface (SDL_Surface *surface, int x1, int y1, int x2, int y2) +{ + // Copies a surface to the active page + + Uint32 + *pixels = surface->pixels; + + for (int y = y1; y < y2; y++) + for (int x = x1; x < x2; x++) + PIXEL (x, y) = pixels[y * (bgi_maxx + 1) + x] | 0xff000000; + +} // _copysurface () + +// ----- + void readimagefile (char *bitmapname, int x1, int y1, int x2, int y2) { - // Reads a .bmp file and displays it immediately at (x1, y1 ). + // Reads a .bmp file and displays it immediately at (x1, y1). check_initgraph (); - Uint32 - *pixels; SDL_Surface - *bm_surface, + *bmp_surface, *tmp_surface; + SDL_Rect src_rect, dest_rect; // load bitmap - bm_surface = SDL_LoadBMP (bitmapname); - if (NULL == bm_surface) { + + bmp_surface = SDL_LoadBMP (bitmapname); + + if (NULL == bmp_surface) { SDL_Log ("SDL_LoadBMP() error: %s\n", SDL_GetError ()); showerrorbox ("SDL_LoadBMP() error"); return; @@ -5211,8 +5500,8 @@ void readimagefile (char *bitmapname, int x1, int y1, int x2, int y2) // source rect, position and size src_rect.x = 0; src_rect.y = 0; - src_rect.w = bm_surface->w; - src_rect.h = bm_surface->h; + src_rect.w = bmp_surface->w; + src_rect.h = bmp_surface->h; // destination rect, position dest_rect.x = x1 + vp.left; @@ -5237,20 +5526,16 @@ void readimagefile (char *bitmapname, int x1, int y1, int x2, int y2) tmp_surface = SDL_GetWindowSurface (bgi_win[bgi_current_window]); // blit bitmap surface to current surface - SDL_BlitScaled (bm_surface, - &src_rect, - tmp_surface, - &dest_rect); + SDL_BlitScaled (bmp_surface, &src_rect, + tmp_surface, &dest_rect); // copy pixel data from the new surface to the active page - pixels = tmp_surface->pixels; - - for (int y = dest_rect.y; y < dest_rect.y + dest_rect.h; y++) - for (int x = dest_rect.x; x < dest_rect.x + dest_rect.w; x++) - PIXEL (x, y) = pixels[y * (bgi_maxx + 1) + x] | 0xff000000; + copysurface (tmp_surface, dest_rect.x, dest_rect.y, + dest_rect.x + dest_rect.w, dest_rect.y + dest_rect.h); refresh_window (); - SDL_FreeSurface (bm_surface); + SDL_FreeSurface (bmp_surface); + SDL_FreeSurface (tmp_surface); } // readimagefile () @@ -5260,13 +5545,17 @@ void refresh (void) { // Updates the screen. +#ifndef __EMSCRIPTEN__ if (bgi_update_mutex) SDL_LockMutex (bgi_update_mutex); +#endif refresh_window (); +#ifndef __EMSCRIPTEN__ if (bgi_update_mutex) SDL_UnlockMutex (bgi_update_mutex); +#endif } // refresh () @@ -5304,29 +5593,31 @@ void resizepalette (Uint32 newsize) void *ptr; - + check_initgraph (); - + ptr = realloc (bgi_argb_palette, (BGI_COLORS + TMP_COLORS + PALETTE_SIZE) * sizeof (Uint32)); if (NULL == ptr) { - char *str = + char *str = "Could not resize the global palette; leaving it unchanged.\n"; fprintf (stderr, "%s", str); showinfobox (str); exit (0); } - + bgi_argb_palette = ptr; PALETTE_SIZE = newsize; - + } // resizepalette () // ----- // callback for sdlbgiauto () +#ifndef __EMSCRIPTEN__ + static Uint32 updatecallback (Uint32 interval, void *param) { if (bgi_update_mutex) @@ -5344,22 +5635,28 @@ static Uint32 updatecallback (Uint32 interval, void *param) } // updatecallback () +#endif + // ----- static void update (void) { // Conditionally refreshes the screen or schedule it +#ifndef __EMSCRIPTEN__ if (bgi_update_mutex) SDL_LockMutex (bgi_update_mutex); +#endif if (! bgi_fast_mode) refresh_window (); else bgi_refresh_needed = SDL_TRUE; +#ifndef __EMSCRIPTEN__ if (bgi_update_mutex) SDL_UnlockMutex (bgi_update_mutex); +#endif } // update () @@ -5369,16 +5666,20 @@ static void update_pixel (int x, int y) { // Updates a single pixel +#ifndef __EMSCRIPTEN__ if (bgi_update_mutex) SDL_LockMutex (bgi_update_mutex); +#endif if (! bgi_fast_mode) updaterect (x, y, x, y); else bgi_refresh_needed = SDL_TRUE; +#ifndef __EMSCRIPTEN__ if (bgi_update_mutex) SDL_UnlockMutex (bgi_update_mutex); +#endif } // update_pixel () @@ -5387,7 +5688,8 @@ static void update_pixel (int x, int y) void sdlbgiauto (void) { // Triggers "auto refresh mode", i.e. refresh() is performed - // automatically on a separate thread. + // automatically on a separate thread. + // Auto mode can't work in Emscripten. check_initgraph (); @@ -5410,8 +5712,13 @@ void sdlbgiauto (void) interval = (Uint32) 1000.0 / bgi_refresh_rate; +#ifndef __EMSCRIPTEN__ // install a timer to periodically update the screen SDL_AddTimer (interval, updatecallback, NULL); +#else + (void) interval; +#endif + bgi_fast_mode = SDL_TRUE; bgi_auto_mode = SDL_TRUE; @@ -5450,12 +5757,12 @@ void setallrgbpalette (struct rgbpalettetype *palette) // Sets the current RGB palette to the values given in palette. check_initgraph (); - + if (NULL == palette) return; palette->size = PALETTE_SIZE; - + for (int i = 0; i < PALETTE_SIZE; i++) bgi_argb_palette[BGI_COLORS + TMP_COLORS + i] = palette->colors[i]; @@ -5467,11 +5774,12 @@ void setalpha (int col, Uint8 alpha) { // Sets alpha transparency for 'col' to 'alpha' (0-255). - Uint32 tmp; + Uint32 + tmp; if (col < -1) return; - + // COLOR () or COLOR32 () or RGBPALETTE() set the ARGB_FG_COL colour if (-1 == col) bgi_fg_color = ARGB_FG_COL; @@ -5503,7 +5811,7 @@ void setbkrgbcolor (int colornum) void setblendmode (int blendmode) { - // Sets the blending mode; it can be either + // Sets the blending mode; it can be either // SDL_BLENDMODE_NONE or SDL_BLENDMODE_BLEND bgi_blendmode = blendmode; @@ -5561,7 +5869,7 @@ void setrgbpalette (int colornum, int red, int green, int blue) // r, g, and b components. check_initgraph (); - + if (colornum < PALETTE_SIZE + 1 && colornum >= 0) bgi_argb_palette[BGI_COLORS + TMP_COLORS + colornum] = 0xff000000 | red << 16 | green << 8 | blue; @@ -5721,14 +6029,14 @@ static void updaterect (int x1, int y1, int x2, int y2) } SDL_RenderPresent (bgi_rnd[bgi_current_window]); -} // updaterect() +} // updaterect () // ----- void writeimagefile (char *filename, int left, int top, int right, int bottom) { - // Writes a .bmp file from the screen rectangle defined by + // Writes a .bmp file from the screen rectangle defined by // 'left', 'top', 'right', 'bottom'. check_initgraph (); @@ -5778,22 +6086,27 @@ int xkbhit (void) // Returns 1 when any key is pressed, or QUIT // if the user asked to close the window - SDL_Event event; + SDL_Event + event; update (); - if (SDL_TRUE == bgi_xkey_pressed) { // a key was pressed during delay() + // ??? bgi_xkey_pressed ??? + if (SDL_TRUE == bgi_xkey_pressed) { // a key was pressed during delay () bgi_xkey_pressed = SDL_FALSE; return SDL_TRUE; } if (SDL_PollEvent (&event)) { - if (SDL_KEYDOWN == event.type) + if (SDL_KEYDOWN == event.type) { + bgi_last_event = SDL_KEYDOWN; + bgi_last_key_pressed = (int) event.key.keysym.sym; return SDL_TRUE; + } else if (SDL_WINDOWEVENT == event.type) { if (SDL_WINDOWEVENT_CLOSE == event.window.event) - return QUIT; + return SDL_QUIT; } else SDL_PushEvent (&event); // don't disrupt the mouse diff --git a/src/SDL_bgi.h b/src/SDL_bgi.h index f791e0d..f8727ec 100644 --- a/src/SDL_bgi.h +++ b/src/SDL_bgi.h @@ -7,13 +7,13 @@ // By Guido Gonzato, PhD // Automatic refresh patch, CHR font support: // Marco Diego Aurélio Mesquita -// Latest update: September 16, 2021 +// Latest update: May 28, 2022 // ZLib License /* -Copyright (c) 2014-2021 Guido Gonzato, PhD +Copyright (c) 2014-2022 Guido Gonzato, PhD This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -43,13 +43,16 @@ freely, subject to the following restrictions: #include #include #include - #include // for fprintf() #include // for exit(), calloc() #include // for sin(), cos() #include // for strlen(), memcpy() -#define SDL_BGI_VERSION 2.5.0 +#ifdef __EMSCRIPTEN__ +#include +#endif + +#define SDL_BGI_VERSION 2.6.0 enum { NOPE, YEAH } ; #define BGI_WINTITLE_LEN 512 // more than enough @@ -153,15 +156,25 @@ enum { USER_FILL // user defined fill }; -// mouse buttons +// mouse events - compatible with WinBGIm + +#define WM_MOUSEMOVE SDL_MOUSEMOTION -#define WM_LBUTTONDOWN SDL_BUTTON_LEFT -#define WM_MBUTTONDOWN SDL_BUTTON_MIDDLE -#define WM_RBUTTONDOWN SDL_BUTTON_RIGHT -#define WM_WHEEL SDL_MOUSEWHEEL -#define WM_WHEELUP SDL_USEREVENT -#define WM_WHEELDOWN SDL_USEREVENT + 1 -#define WM_MOUSEMOVE SDL_MOUSEMOTION +#define WM_LBUTTONDOWN SDL_BUTTON_LEFT +#define WM_LBUTTONUP SDL_MOUSEBUTTONUP + SDL_BUTTON_LEFT +#define WM_LBUTTONDBLCLK SDL_MOUSEBUTTONDOWN + SDL_BUTTON_LEFT + 2 + +#define WM_MBUTTONDOWN SDL_BUTTON_MIDDLE +#define WM_MBUTTONUP SDL_MOUSEBUTTONUP + 10*SDL_BUTTON_MIDDLE +#define WM_MBUTTONDBLCLK SDL_MOUSEBUTTONDOWN + 10*SDL_BUTTON_MIDDLE + 2 + +#define WM_RBUTTONDOWN SDL_BUTTON_RIGHT +#define WM_RBUTTONUP SDL_MOUSEBUTTONUP + 20*SDL_BUTTON_RIGHT +#define WM_RBUTTONDBLCLK SDL_MOUSEBUTTONDOWN + 20*SDL_BUTTON_RIGHT + 2 + +#define WM_WHEEL SDL_MOUSEWHEEL +#define WM_WHEELUP SDL_BUTTON_RIGHT + 1 +#define WM_WHEELDOWN SDL_BUTTON_RIGHT + 2 // keys #define KEY_HOME SDLK_HOME @@ -366,7 +379,7 @@ void getarccoords (struct arccoordstype *); void getaspectratio (int *, int *); int getbkcolor (void); int bgi_getch (void); -// circumvents Mingw bug +// circumvent Mingw bug #define getch bgi_getch int getcolor (void); struct palettetype @@ -402,9 +415,10 @@ unsigned void initgraph (int *, int *, char *); int installuserdriver (char *, int (*)(void)); int installuserfont (char *); -// circumvents Mingw bug +// circumvent Mingw bug int bgi_kbhit (void); #define kbhit bgi_kbhit +int lastkey (void); void line (int, int, int, int); void linerel (int, int); void lineto (int, int); @@ -452,11 +466,14 @@ void closewindow (int); int COLOR (int, int, int); int COLOR32 (Uint32); #define colorRGB(r,g,b) 0xff000000 | ((r) << 16) | ((g) << 8) | (b) -int edelay (int); +void copysurface (SDL_Surface *, int, int, int, int); +int doubleclick (void); +int edelay (int); int event (void); int eventtype (void); // void freeimage (void *); void getbuffer (Uint32 *); +int getclick (void); int getcurrentwindow (void); void getleftclick (void); int getevent (void); @@ -500,8 +517,9 @@ void setwintitle (int, char *); void showinfobox (const char *); void showerrorbox (const char *); void swapbuffers (void); +void winclose (void); int xkbhit (void); - + #ifdef __cplusplus } #endif diff --git a/src/graphics.h b/src/graphics.h index 093915c..943b7a5 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -3,7 +3,7 @@ // `SDL_bgi` is a multiplatform, SDL2-based `graphics.h` implementation. // Easy to use, pretty fast, and useful for porting old programs. // Guido Gonzato, PhD -// November 11, 2020 +// April 19, 2022 #include diff --git a/test/Makefile b/test/Makefile index 1af654c..efbbff6 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,7 +1,8 @@ # Makefile for test SDL_bgi programs # Please note that f90_test.f90 is not included -# C compiler: gcc or clang +# C compiler: gcc, clang, or tcc +# CC = tcc -w -D SDL_DISABLE_IMMINTRIN_H CC = gcc # Detect the platform: GNU/Linux, Darwin (macOS), Mingw-w64 @@ -22,16 +23,17 @@ endif # Latest MSYS2 + Mingw-w64 msys := $(findstring _NT, $(PLATFORM)) ifeq ($(msys),_NT) +# use MinGW-64 native SDL2 packages CFLAGS = -std=gnu99 -O2 -g -I. -I/mingw64/include -I/mingw64/include/SDL # -mconsole = open a console alongside the program # -mwindows = Windows-only program (no console) LIBS = -lmingw32 -L/mingw64/bin -lSDL_bgi -lSDL2main -lSDL2 # -mwindows endif -PROGRAMS = boo buffers cellular dla fern floodfilltest fonts \ - hopalong life linebuffers kaleido mandelbrot mousetest \ - multiwin plasma psychedelia rgbpalette sdlbgidemo \ - simple turtledemo +PROGRAMS = boo buffers cellular dla fern floodfilltest \ + fonts hopalong kaleido life linebuffers \ + mandelbrot mousetest multiwin plasma pdj psychedelia \ + rgbpalette sdlbgidemo simple turtledemo all: $(PROGRAMS) @@ -49,7 +51,7 @@ endif bgidemo.c: ifdef WGET - wget http://libxbgi.sourceforge.net/bgidemo.c + wget http://sdl-bgi.sourceforge.io/bgidemo.c else $(info Could not find 'wget', can't download bgidemo.c) endif @@ -84,6 +86,10 @@ life: life.c linebuffers: linebuffers.c $(CC) $(CFLAGS) -o linebuffers linebuffers.c $(LIBS) +# you need SDL2_Image to compile this program +loadimage: loadimage.c + $(CC) $(CFLAGS) -o loadimage loadimage.c $(LIBS) -lSDL2_image + kaleido: kaleido.c $(CC) $(CFLAGS) -o kaleido kaleido.c $(LIBS) @@ -96,6 +102,9 @@ mousetest: mousetest.c multiwin: multiwin.c $(CC) $(CFLAGS) -o multiwin multiwin.c $(LIBS) +pdj: pdj.c + $(CC) $(CFLAGS) -o pdj pdj.c $(LIBS) -lm + plasma: plasma.c $(CC) $(CFLAGS) -o plasma plasma.c $(LIBS) -lm @@ -115,6 +124,6 @@ turtledemo: turtledemo.c turtle.c $(CC) $(CFLAGS) -o turtledemo turtledemo.c turtle.c $(LIBS) -lm clean: - rm -rf $(PROGRAMS) bgidemo* a.out *o f90_test *dSYM + /bin/rm -rf $(PROGRAMS) bgidemo.c *~ a.out *o f90_test *dSYM *exe # --- end of Makefile diff --git a/test/Makefile.emcc b/test/Makefile.emcc new file mode 100644 index 0000000..1d49a91 --- /dev/null +++ b/test/Makefile.emcc @@ -0,0 +1,105 @@ +# Makefile for test SDL_bgi programs, to be compiled +# to Webassembly using Emscripten +# Latest update: May 28, 2022 + +CC = emcc +SHELL1 = --shell-file ./shells/canvas_only.html +SHELL2 = --shell-file ./shells/sdl_bgi.html +CFLAGS = -std=gnu99 -O2 -Wall -lSDL_bgi -I. \ + --embed-file ./assets@/. \ + -s USE_SDL=2 -s ALLOW_MEMORY_GROWTH=1 -s ASYNCIFY -s SINGLE_FILE + +EMCC := $(shell command -v $(CC) 2> /dev/null) +ifndef EMCC + $(error emcc not found, exiting.) +endif + +PROGRAMS = boo.html buffers.html cellular.html dla.html fern.html \ + floodfilltest.html fonts.html hopalong.html kaleido.html \ + life.html linebuffers.html mandelbrot.html mousetest.html \ + multiwin.html pdj.html psychedelia.html rgbpalette.html \ + sdlbgidemo.html simple.html + +all: $(PROGRAMS) + +WGET := $(shell command -v wget 2> /dev/null) + +bgidemo.html: bgidemo.c +ifeq ($(msys),_NT) + # fix wrong main() definition + sed -i 's/main()/main(int argc, char *argv[])/' bgidemo.c +endif + echo "VGA" > assets/SDL_BGI_RES; \ + echo "BGI" > assets/SDL_BGI_PALETTE; \ + $(CC) $(CFLAGS) $(SHELL1) \ + -o bgidemo.html bgidemo.c ; \ + /bin/rm -f assets/SDL_BGI_* + +bgidemo.c: +ifdef WGET + wget http://sdl-bgi.sourceforge.io/bgidemo.c +else + $(info Could not find 'wget', can't download bgidemo.c) +endif + +boo.html: boo.c + $(CC) $(CFLAGS) $(SHELL1) -o boo.html boo.c + +buffers.html: buffers.c + $(CC) $(CFLAGS) $(SHELL1) -o buffers.html buffers.c + +cellular.html: cellular.c + $(CC) $(CFLAGS) $(SHELL1) -o cellular.html cellular.c + +dla.html: dla.c + $(CC) $(CFLAGS) $(SHELL2) -o dla.html dla.c + +fern.html: fern.c + $(CC) $(CFLAGS) $(SHELL1) -o fern.html fern.c + +floodfilltest.html: floodfilltest.c + $(CC) $(CFLAGS) $(SHELL1) -o floodfilltest.html floodfilltest.c + +fonts.html: fonts.c + $(CC) $(CFLAGS) $(SHELL1) -o fonts.html fonts.c + +hopalong.html: hopalong.c + $(CC) $(CFLAGS) $(SHELL2) -o hopalong.html hopalong.c + +life.html: life.c + $(CC) $(CFLAGS) $(SHELL1) -o life.html life.c + +linebuffers.html: linebuffers.c + $(CC) $(CFLAGS) $(SHELL1) -o linebuffers.html linebuffers.c + +kaleido.html: kaleido.c + $(CC) $(CFLAGS) $(SHELL1) -o kaleido.html kaleido.c + +mandelbrot.html: mandelbrot.c + $(CC) $(CFLAGS) $(SHELL1) -o mandelbrot.html mandelbrot.c + +mousetest.html: mousetest.c + $(CC) $(CFLAGS) $(SHELL1) -o mousetest.html mousetest.c + +multiwin.html: multiwin.c + $(CC) $(CFLAGS) $(SHELL1) -o multiwin.html multiwin.c + +pdj.html: pdj.c + $(CC) $(CFLAGS) $(SHELL2) -o pdj.html pdj.c + +psychedelia.html: psychedelia.c + $(CC) $(CFLAGS) $(SHELL1) -o psychedelia.html psychedelia.c + +rgbpalette.html: rgbpalette.c + $(CC) $(CFLAGS) $(SHELL1) -o rgbpalette.html rgbpalette.c + +sdlbgidemo.html: sdlbgidemo.c + $(CC) $(CFLAGS) $(SHELL1) -o sdlbgidemo.html sdlbgidemo.c + +simple.html: simple.c + $(CC) $(CFLAGS) $(SHELL1) -o simple.html simple.c + +clean: + rm -rf *wasm *js *html *~ + +# --- end of Makefile diff --git a/test/README.md b/test/README.md index 131a0d2..09c97cb 100644 --- a/test/README.md +++ b/test/README.md @@ -1,10 +1,21 @@ -Test programs for SDL_bgi -------------------------- +# Test programs for `SDL_bgi` By Guido Gonzato, PhD This directory contains a few simple programs that show how to use -some features of `SDL_bgi`; type `make` to compile them. +some features of `SDL_bgi`. You can compile these programs to native +executables using a standard C compiler, or to WebAssembly embedded in +html files using the Emscripten `emcc` compiler. + +To compile the programs as native executables, type `make`; to compile +them to html files, type `make -f Makefile.emcc`. The resulting +html files can be loaded and run in any web browser, without the need +of a local web server (no need to use `emrun`). + +If you use the `tcc` compiler, you can run your program using the +provided `tccrun` shell script (GNU/Linux only). For example: + + ./tccrun life.c 20 You may want to compile the original `bgidemo.c` program by Borland. It's not free software, so it's not included here. However, it can be @@ -12,11 +23,8 @@ downloaded from several sources; type `make bgidemo` to download and compile it. You will need the `wget` tool in the $PATH. By default, `bgidemo` fails to build on MSYS2 because of its wrong -`main()` declaration; the Makefiles calls 'sed' to change `int main()` -to `int main(int argc, char *argv[])`. - -There may be compiler warnings using gcc releases newer than 7, as in -Ubuntu 20. +`main()` declaration; to fix is, Makefile calls 'sed' to change `int +main()` to `int main(int argc, char *argv[])`. License: all programs are released under GPL2 or later. @@ -58,13 +66,17 @@ fade away effect. `./life [number]`, where `[number]` is the initial percentage of living cells. +- `loadimage.c` shows how to load .png (or .jpg) pictures using +SDL2_Image (required to compile this program) and copysurface(). +Type `make loadimage` to compile. + - `linebuffers.c` shows how to use `getlinebuffer()` and `putlinebuffer()` to draw pixel-based stuff on the screen. Using buffers (i.e. arrays) is much faster than using `putpixel()`. - `mandelbrot.c` is a simple, non-optimised program to display the Mandelbrot set, . It -shows how to setup and use RGB colour mode. Press '1', '2', '3' to +shows how to setup and use RGB colour mode. Press '1', '2', '3' to4<< change the palette; left click to zoom in on a point; right click to zoom out; arrow keys to move around; middle click to restore the initial boundary. @@ -74,6 +86,10 @@ using all buttons and mouse wheel. - `multiwin.c` shows how to open multiple windows. +- `pdj.c` plots Peter de Jong attractors, +. Press any key to plot a +new random attractor, or ESC to exit. + - `plasma.c` writes the window contents to a `.bmp` file. - `psychedelia.c` sets up an RGB palette and produces a plasma effect, @@ -96,8 +112,7 @@ Besides, 'f90_test' shows how to use `SDL_bgi` in Fortran programs. Kindly provided by Angelo Graziosi. -Notes on Turtle Graphics ------------------------- +# Notes on Turtle Graphics Turtle graphics is based on polar coordinates: you draw lines specifying the distance in pixels and an angle in degrees, called diff --git a/test/assets/logo.bmp b/test/assets/logo.bmp new file mode 100644 index 0000000..eef2e7b Binary files /dev/null and b/test/assets/logo.bmp differ diff --git a/test/assets/logo.png b/test/assets/logo.png new file mode 100644 index 0000000..33609cd Binary files /dev/null and b/test/assets/logo.png differ diff --git a/test/assets/plasma.bmp b/test/assets/plasma.bmp new file mode 100644 index 0000000..06fde3a Binary files /dev/null and b/test/assets/plasma.bmp differ diff --git a/test/buffers.c b/test/buffers.c index df1dfdf..cf3b385 100644 --- a/test/buffers.c +++ b/test/buffers.c @@ -5,6 +5,9 @@ * * getbuffer() / putbuffer() demonstration. * + * !!! Does not work in Emscripten: + * "Uncaught RuntimeError: memory access out of bounds" + * * By Guido Gonzato, January 2020. * * This program is free software; you can redistribute it and/or modify @@ -52,16 +55,16 @@ int main (int argc, char *argv[]) setcolor (BLACK); setbkcolor (WHITE); cleardevice (); - outtextxy (0, 0, "Left click to continue:"); + outtextxy (0, 0, "Click to continue:"); refresh (); - getleftclick (); + getclick (); putbuffer (red[0]); getbuffer (tmp[0]); // tmp == red setcolor (WHITE); outtextxy (0, 0, "Left click to continue:"); refresh (); - getleftclick (); + getclick (); for (alpha = 0; alpha < 128; alpha++) { @@ -74,14 +77,16 @@ int main (int argc, char *argv[]) putbuffer (tmp[0]); // red screen putbuffer (hues[0]); // hues + alpha on red refresh (); - delay (50); + delay (10); } // for alpha outtextxy (0, 0, "Left click to finish:"); refresh (); - getleftclick (); + getclick (); closegraph (); -} \ No newline at end of file +} + +// ----- end of file buffers.c diff --git a/test/dla.c b/test/dla.c index 9015627..c000228 100644 --- a/test/dla.c +++ b/test/dla.c @@ -62,6 +62,13 @@ int main (int argc, char *argv[]) initgraph (&gd, &gm, ""); setbkcolor (BLACK); + setcolor (RED); + cleardevice (); + settextjustify (CENTER_TEXT, CENTER_TEXT); + outtextxy (getmaxx() / 2, getmaxy () / 2, + "Press a key to exit"); + + getch (); cleardevice (); iterations = 0; @@ -95,7 +102,7 @@ int main (int argc, char *argv[]) random_walk (); if (iterations % 5000) { - if (xkbhit ()) + if (kbhit ()) stop = 1; } } diff --git a/test/emcc.sh b/test/emcc.sh new file mode 100644 index 0000000..2465c75 --- /dev/null +++ b/test/emcc.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +# This script compiles a .C source using emscripten, which is +# assumed to be installed and working. To run the resulting program, +# open $NAME.html in a web browser. + +# Tested on GNU/Linux only! + +if [ $# -eq 0 ] ; then + echo "Usage: $0 [-c] [-f] [-m] [-s] " + exit 1 +fi + +if ! [ -x "$(command -v emcc)" ]; then + echo 'Error: emcc is not installed.' >&2 + exit 1 +fi + +SHELLFILE="" +SHELL="" + +while getopts ":cfmsh" opt; do + case ${opt} in + c ) SHELLFILE="./shells/canvas_only.html" + ;; + f ) SHELLFILE="./shells/fullwindow.html" + ;; + m ) SHELLFILE="./shells/shell_minimal.html" + ;; + s ) SHELLFILE="./shells/sdl_bgi.html" + ;; + h ) echo "Usage: $0 [-c] [-f] [-m] [-s] " + echo "-c: use ./shells/canvas_only.html" + echo "-f: use ./shells/fullwindow.html" + echo "-m: use ./shells/shell_minimal.html" + echo "-s: use ./shells/sdl_bgi.html" + exit 1 + ;; + esac +done + +if [ -n "$SHELLFILE" ] ; then + SHELL="--shell-file "$SHELLFILE +fi + +# program must be the last argument +for arg in "$@" ; do : ; done + +NAME=$(basename $arg .c) + +# load files in 'assets/' as if they were in local directory '.' +EMBED="--embed-file ./assets@/." +CFLAGS="-std=gnu99 -O2 -Wall" + +emcc $CFLAGS -o $NAME.html \ +$SHELL $INCLUDE $EMBED $NAME.c -lSDL_bgi \ +-s USE_SDL=2 \ +-s ALLOW_MEMORY_GROWTH=1 \ +-s ASYNCIFY \ +-s SINGLE_FILE + +# --- end of file emcc.sh diff --git a/test/fern.c b/test/fern.c index 69170a6..b387af6 100644 --- a/test/fern.c +++ b/test/fern.c @@ -122,7 +122,7 @@ int main (int argc, char *argv[]) if (kbhit ()) stop = 1; } - if (10000000 == counter) /* 10 million pixels */ + if (100000000 == counter) /* 100 million pixels */ break; } setcolor (GREEN); @@ -132,4 +132,4 @@ int main (int argc, char *argv[]) return 0; } -/* -- end of file fern.c --- */ +/* ----- end of file fern.c ----- */ diff --git a/test/floodfilltest.c b/test/floodfilltest.c index 6804d32..0b2d277 100644 --- a/test/floodfilltest.c +++ b/test/floodfilltest.c @@ -32,7 +32,7 @@ int main (int argc, char *argv[]) int stop = 0, - p; + mclick; initwindow (800, 600); setbkcolor (BLACK); @@ -46,30 +46,32 @@ int main (int argc, char *argv[]) "right click to fill;"); outtextxy (getmaxx() / 2, getmaxy () / 2 + 15, "press a key to exit."); - refresh (); + getevent (); + cleardevice (); setcolor (YELLOW); + refresh (); while (! stop) { - if ((p = mouseclick ())) { - if (WM_LBUTTONDOWN == p) { - setcolor (YELLOW); - circle (mousex (), mousey (), random (100)); - // added! - refresh (); - } - else - if (WM_RBUTTONDOWN == p) { - setcolor (random (MAXCOLORS)); - setfillstyle (1 + random(USER_FILL), - COLOR (random (255), random (255), random (255))); - floodfill (mousex (), mousey (), YELLOW); - refresh (); - } + mclick = getevent (); + + if (WM_LBUTTONDOWN == mclick) { + setcolor (YELLOW); + circle (mousex (), mousey (), 10 + random (100)); + refresh (); + } + + if (WM_RBUTTONDOWN == mclick) { + setcolor (random (MAXCOLORS)); + setfillstyle (1 + random(USER_FILL), + COLOR (random (255), random (255), random (255))); + floodfill (mousex (), mousey (), YELLOW); + refresh (); } - if (xkbhit ()) + + if (KEY_ESC == mclick) stop = 1; } // while diff --git a/test/fonts.c b/test/fonts.c index 5444c42..d60bba2 100644 --- a/test/fonts.c +++ b/test/fonts.c @@ -94,7 +94,7 @@ int main (int argc, char *argv[]) outtextxy (10, pos_y += v_skip, str_az); pos_y += v_skip + 15; - getch (); + getevent (); cleardevice (); pos_y = 5; @@ -125,7 +125,7 @@ int main (int argc, char *argv[]) outtextxy (10, pos_y += v_skip, str_az); pos_y += v_skip + 20; - getch (); + getevent (); cleardevice (); pos_y = 5; @@ -155,7 +155,7 @@ int main (int argc, char *argv[]) outtextxy (10, pos_y += v_skip, str_AZ); outtextxy (10, pos_y += v_skip, str_az); - getch (); + getevent (); cleardevice (); settextstyle (TRIPLEX_FONT, VERT_DIR, 0); @@ -176,7 +176,7 @@ int main (int argc, char *argv[]) outtextxy (getmaxx () * 0.75, getmaxy () / 2, "This is VERTICAL TEXT"); - getch (); + getevent (); cleardevice (); pos_y = 5; @@ -210,7 +210,7 @@ int main (int argc, char *argv[]) outtextxy (10, pos_y += v_skip, str_az); pos_y += v_skip + 20; - getch (); + getevent (); closegraph (); } /* main () */ diff --git a/test/hopalong.c b/test/hopalong.c index 659b920..57699d0 100644 --- a/test/hopalong.c +++ b/test/hopalong.c @@ -77,13 +77,13 @@ int main (int argc, char *argv[]) counter = 0; setcolor (COLOR (random (256), random (256), random (256))); refresh (); - if (event ()) + if (ismouseclick (WM_LBUTTONDOWN) || kbhit ()) stop = 1; } } closegraph (); - if (SDL_KEYDOWN == eventtype()) + if (SDL_KEYDOWN == eventtype ()) puts ("Key pressed."); else puts ("Mouse clicked."); diff --git a/test/kaleido.c b/test/kaleido.c index e7ff53d..faf53be 100644 --- a/test/kaleido.c +++ b/test/kaleido.c @@ -84,10 +84,14 @@ int main (int argc, char *argv[]) setwinoptions ("", -1, -1, SDL_WINDOW_FULLSCREEN); initwindow (0, 0); // fullscreen setbkcolor (BLACK); + setcolor (RED); cleardevice (); refresh (); xc = getmaxx () / 2; yc = getmaxy () / 2; + settextjustify (CENTER_TEXT, CENTER_TEXT); + outtextxy (xc, yc, "Press a key to start:"); + getch (); n = 0; while (!stop) { @@ -125,7 +129,7 @@ int main (int argc, char *argv[]) refresh (); n = 0; - if (event()) + if (WM_LBUTTONDOWN == mouseclick()) stop = YEAH; } @@ -134,3 +138,5 @@ int main (int argc, char *argv[]) closegraph (); } + +// ----- end of file kaleido.c diff --git a/test/life.c b/test/life.c index a1e98de..8668ad8 100644 --- a/test/life.c +++ b/test/life.c @@ -6,7 +6,9 @@ * Simple cellular automaton, as described at * http://mathworld.wolfram.com/ElementaryCellularAutomaton.html * - * By Guido Gonzato, May 2015. + * This version can be compiled to Webassembly using emscripten. + * + * By Guido Gonzato, May 2022. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,31 +32,39 @@ #include +#ifdef __EMSCRIPTEN__ +#include +#endif + + #define SIZE 500 #define ALIVE 1 #define DEAD 0 char a[SIZE][SIZE], b[SIZE][SIZE]; + void print_cells (char[SIZE][SIZE]); void evolve_cells (char[SIZE][SIZE], char[SIZE][SIZE]); +void initialise (int); -int main (int argc, char *argv[]) +// ----- + +void initialise (int percentage) { - int x, y, stop = 0; - unsigned int percent; - unsigned long iterations = 0; - - srand (time(NULL)); - if (2 == argc) - percent = atoi (argv [1]); // no checks! - else - percent = 10; - - for (x = 0; x < SIZE; x++) - for (y = 0; y < SIZE; y++) - a[x][y] = (random (100) < percent) ? ALIVE: DEAD; - - initwindow (SIZE, SIZE); + for (int x = 0; x < SIZE; x++) + for (int y = 0; y < SIZE; y++) + a[x][y] = (random (100) < percentage) ? ALIVE: DEAD; +} + +// ----- + +void main_loop (void) +{ + + unsigned long + iterations = 0; + int + stop = 0; while (! stop) { evolve_cells (a, b); @@ -64,9 +74,34 @@ int main (int argc, char *argv[]) print_cells (a); refresh (); if (++iterations % 1000) - if (xkbhit ()) - stop = 1; + if (kbhit ()) { + if (KEY_ESC == lastkey ()) + stop = 1; + else + initialise (random (100)); + } } + +} // --- main_loop () + +// ----- + +int main (int argc, char *argv[]) +{ + unsigned int percentage; + + srand (time(NULL)); + if (2 == argc) + percentage = atoi (argv [1]); // no checks! + else + percentage = 10; + + showinfobox ("Press any key to restart,\n" + "or ESC to exit."); + + initialise (percentage); + initwindow (SIZE, SIZE); + main_loop (); closegraph (); diff --git a/test/linebuffers.c b/test/linebuffers.c index 3026b4b..8cd126b 100644 --- a/test/linebuffers.c +++ b/test/linebuffers.c @@ -29,7 +29,6 @@ #define WIDTH 256 #define HEIGHT 256 - void shiftbuffer (Uint32 *line) { // scroll line elements 1 position to the left @@ -39,7 +38,7 @@ void shiftbuffer (Uint32 *line) tmp = line[0]; memmove ( (void *) &line[0], (const void *) &line[1], - (size_t) (WIDTH * sizeof (Uint32)) ); + (size_t) ((WIDTH - 1) * sizeof (Uint32)) ); line[WIDTH - 1] = tmp; } // shiftbuffer() @@ -60,23 +59,16 @@ int main (int argc, char *argv[]) setwinoptions ("Using putlinebuffer()", -1, -1, -1); initwindow (WIDTH, HEIGHT); - putbuffer (hues[0]); refresh (); showinfobox ("Left click to switch between\n" "putlinebuffer() and putpixel();\n" - "any key to stop."); - + "right click to stop."); + + putbuffer (hues[0]); + refresh (); int mode = 1; - while (! xkbhit ()) { - - if (WM_LBUTTONDOWN == mouseclick ()) { - mode ^= 1; - if (1 == mode) - puts ("using getlinebuffer()/putlinebuffer()"); - else - puts ("using getpixel()/putpixel()"); - } + while (! ismouseclick (WM_RBUTTONDOWN)) { if (1 == mode) { for (int y = 0; y < HEIGHT; y++) { @@ -95,6 +87,14 @@ int main (int argc, char *argv[]) } } + if (WM_LBUTTONDOWN == mouseclick ()) { + mode ^= 1; + if (1 == mode) + puts ("using getlinebuffer()/putlinebuffer()"); + else + puts ("using getpixel()/putpixel()"); + } + delay (5); refresh (); diff --git a/test/loadimage.c b/test/loadimage.c new file mode 100644 index 0000000..6430330 --- /dev/null +++ b/test/loadimage.c @@ -0,0 +1,121 @@ +/* loadimage.c -*- C -*- + * + * To compile: + * gcc -o loadimage loadimage.c -lSDL_bgi -lSDL2 -lSDL2_image + * + * Shows how to load images using IMG_Load(), provided + * by SDL_image. + * + * By Guido Gonzato, January 2022. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include + +void loadimagefile (char *filename, int x1, int y1, int x2, int y2) +{ + // Reads a graphics file and displays it immediately at (x1, y1 ). + + SDL_Surface + *image_surface, + *tmp_surface; + + SDL_Rect + src_rect, + dest_rect; + + // load image file to surface + image_surface = IMG_Load (filename); + + if (NULL == image_surface) { + SDL_Log ("IMG_Load () error: %s\n", IMG_GetError ()); + showerrorbox ("IMG_Load () error"); + return; + } + + // source rect, position and size + src_rect.x = 0; + src_rect.y = 0; + src_rect.w = image_surface->w; + src_rect.h = image_surface->h; + + // destination rect, position + dest_rect.x = x1; + dest_rect.y = y1; + + if (0 == x2 || 0 == y2) { // keep original size + dest_rect.w = src_rect.w; + dest_rect.h = src_rect.h; + } + else { // change size + dest_rect.w = x2 - x1 + 1; + dest_rect.h = y2 - y1 + 1; + } + + // get SDL surface from current window + tmp_surface = SDL_GetWindowSurface (bgi_window); + + // blit bitmap surface to current surface + SDL_BlitScaled (image_surface, &src_rect, + tmp_surface, &dest_rect); + + copysurface (tmp_surface, dest_rect.x, dest_rect.y, + dest_rect.x + dest_rect.w, dest_rect.y + dest_rect.h); + + refresh (); + SDL_FreeSurface (image_surface); + SDL_FreeSurface (tmp_surface); + +} // loadimagefile () + +// ----- + +int main (int argc, char *argv[]) +{ + + // Load an image in a window of the same size. + + SDL_Surface + *image_surface; + + if (1 == argc) { + fprintf (stderr, "Usage: %s \n", argv[0]); + fprintf (stderr, + " can be any image type supported by SDL2_image.\n"); + return 1; + } + + IMG_Init (IMG_INIT_PNG | IMG_INIT_JPG | IMG_INIT_TIF); + + // load image to get the size + image_surface = IMG_Load (argv[1]); + // init a window as large as the image + initwindow (image_surface->w, image_surface->h); + SDL_FreeSurface (image_surface); + // load the image + loadimagefile (argv[1], 0, 0, 0, 0); + getch (); + + IMG_Quit (); + closegraph (); + + return 0; + +} + +// ----- end of file loadimage.c diff --git a/test/logo.png b/test/logo.png new file mode 100644 index 0000000..33609cd Binary files /dev/null and b/test/logo.png differ diff --git a/test/mandelbrot.c b/test/mandelbrot.c index 793562a..b83c901 100644 --- a/test/mandelbrot.c +++ b/test/mandelbrot.c @@ -3,7 +3,7 @@ * To compile: * gcc -o mandelbrot mandelbrot.c -lSDL_bgi -lSDL2 * - * By Guido Gonzato, May 2015 + * By Guido Gonzato, May 2015-2022 * * This is an unoptimised, simple but effective program for plotting * the Mandelbrot set. Left click to zoom in on a point, right click @@ -68,13 +68,6 @@ void mandelbrot (double x1, double y1, double x2, double y2) counter++; } while (d <= 4.0 && counter < max_iter); - // 16 colour mode: - // int color; - // if (counter == max_iter) - // color = BLACK; - // else - // color = 1 + counter % 15; - setrgbcolor (counter); _putpixel (xx, yy); y += dy; @@ -125,6 +118,19 @@ void blue_palette (void) // ----- +void help (void) +{ + showinfobox ("Press '1', '2', or '3' to change the palette\n" + "left click to zoom in on a point\n" + "right click to zoom out\n" + "middle click or 'R' to restore the initial boundary\n" + "'i' or '+', 'd' or '-' to increase/decrease max iterations\n" + "arrow keys to move around\n" + "'Q' to quit the program"); +} // help () + +// ----- + void explain (void) { int @@ -135,36 +141,34 @@ void explain (void) setbkcolor (COLOR (0, 0, 32)); // don't use a palette cleardevice (); setcolor (COLOR (255, 255, 0)); - // setrgbpalette (0, 0, 0, 32); - // setrgbpalette (1, 255, 255, 0); - // setrgbcolor (1); - // setbkrgbcolor (0); - // cleardevice (); - // alternatively, use setrgbcolor() or setbkrgbcolor() settextstyle (TRIPLEX_FONT, HORIZ_DIR, 4); settextjustify (CENTER_TEXT, CENTER_TEXT); c = 2*textheight ("H"); + outtextxy (maxx / 2, maxy / 2 - 4*c, + "Press '1', '2', or '3' to change the palette"); outtextxy (maxx / 2, maxy / 2 - 3*c, - "Press '1', '2', or '3' to change the palette;"); + "left click to zoom in on a point"); outtextxy (maxx / 2, maxy / 2 - 2*c, - "left click to zoom in on a point;"); + "right click to zoom out"); outtextxy (maxx / 2, maxy / 2 - c, - "right click to zoom out;"); + "middle click or 'R' to restore the initial boundary"); outtextxy (maxx / 2, maxy / 2, - "middle click to restore the initial boundary;"); + "'i' or '+', 'd' or '-' to increase/decrease max iterations"); outtextxy (maxx / 2, maxy / 2 + c, - "'i' or '+', 'd' or '-' to increase/decrease max iterations;"); - + "arrow keys to move around"); outtextxy (maxx / 2, maxy / 2 + 2*c, - "arrow keys to move around;"); + "'H' to get help"); outtextxy (maxx / 2, maxy / 2 + 3*c, - "ESC to quit the program."); + "'Q' to quit the program"); - while (! event ()) { + int + ev; + + while (1) { - setcolor(COLOR (i, 0, 0)); + setcolor (COLOR (i, 0, 0)); outtextxy (maxx / 2, maxy / 2 + 4*c, "PRESS A KEY OR CLICK TO BEGIN"); i += inc; if (255 == i) @@ -173,6 +177,12 @@ void explain (void) inc = 5; delay(1); refresh (); + + event (); + ev = eventtype (); + if (ev == SDL_KEYDOWN || ev == SDL_MOUSEBUTTONDOWN) + break; + } cleardevice (); @@ -185,13 +195,11 @@ void explain (void) int main (int argc, char *argv[]) { - int palette, c, init, redraw, flag; + int palette, ch, init, redraw, flag; double xm, ym, xstep, ystep, xmin, ymin, xmax, ymax; char s[20]; initwindow (0, 0); // fullscreen - // setwinoptions ("", -1, -1, SDL_WINDOW_FULLSCREEN); - // initwindow (1024, 768); maxx = getmaxx (); maxy = getmaxy (); @@ -199,8 +207,8 @@ int main (int argc, char *argv[]) xm = -1.2; ym = 0.0; // initial range: xm +- xstep, ym +- ystep - xstep = (double) maxx / (double) maxy; ystep = 1.2; + xstep = ystep * maxx / (double) maxy; init = flag = redraw = 1; explain (); @@ -208,8 +216,8 @@ int main (int argc, char *argv[]) purple_palette (); palette = 1; - c = 'G'; - while (c != KEY_ESC) { + ch = 'G'; + while (ch != 'q' && ch != 'Q') { xmin = xm - xstep; ymin = ym - ystep; @@ -218,7 +226,6 @@ int main (int argc, char *argv[]) if (redraw) { mandelbrot (xmin, ymin, xmax, ymax); - // added! refresh (); if (flag) { setcolor (WHITE); @@ -230,16 +237,19 @@ int main (int argc, char *argv[]) redraw = 0; } - c = getevent (); // wait for a key, mouse click, or wheel motion + ch = getevent (); // wait for a key, mouse click, or wheel motion - switch (c) { + switch (ch) { + + case 'h': + case 'H': + help (); + break; case WM_LBUTTONDOWN: case WM_WHEELUP: xm = xmin + 2 * xstep * mousex () / maxx; ym = ymin + 2 * ystep * mousey () / maxy; - /* xm = xmin + (xmax - xmin) * mousex () / maxx; */ - /* ym = ymin + (ymax - ymin) * mousey () / maxy; */ xstep /= 2.0; ystep /= 2.0; init = 0; @@ -255,11 +265,13 @@ int main (int argc, char *argv[]) break; case WM_MBUTTONDOWN: + case 'r': + case 'R': if (0 == init) { - xm = -0.75; - ym = 0.0; - xstep = 1.6; - ystep = 1.2; + xm = -1.2; + ym = 0.0; + ystep = 1.2; + xstep = ystep * (double) maxx / (double) maxy; redraw = 1; } break; @@ -336,9 +348,9 @@ int main (int argc, char *argv[]) } // while + closegraph (); return 0; } // main(void) () // ----- end of file mandelbrot.c - diff --git a/test/mousetest.c b/test/mousetest.c index 9817293..17c7d18 100644 --- a/test/mousetest.c +++ b/test/mousetest.c @@ -1,10 +1,10 @@ /* mousetest.c -*- C -*- - * + * * To compile: * gcc -o mousetest mousetest.c -lSDL_bgi -lSDL2 - * - * By Guido Gonzato, May 2015 - * + * + * By Guido Gonzato, 2015-2022 + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -18,76 +18,122 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * + * */ #include #include #include -// ----- - int main (int argc, char *argv[]) { - int gd, gm, p, x, y; - char s[] = "Click around (or here to exit)"; - int len; + int + gd, gm = SDL_800x600, + mclick, len, + isize; + char + s[] = " Click around (click here to exit) ", + *image; - gd = SDL; - gm = SDL_1024x768; initgraph (&gd, &gm, ""); setbkcolor (BLACK); setcolor (RED); - setviewport (10, 10, getmaxx() - 10, getmaxy() - 10, 1); - + setviewport (20, 20, getmaxx() - 20, getmaxy() - 20, 1); + clearviewport (); settextjustify (CENTER_TEXT, CENTER_TEXT); - outtextxy (getmaxx() / 2, getmaxy () / 2, - "Click the RIGHT button to begin"); - - getrightclick (); - getmouseclick(WM_RBUTTONDOWN, &x, &y); + outtextxy (getmaxx() / 2, getmaxy () / 2, + "Click to begin"); + + getleftclick (); clearviewport (); - rectangle (0, 0, getmaxx () - 20, getmaxy () - 20); - + rectangle (0, 0, getmaxx () - 40, getmaxy () - 40); + len = strlen(s) * 8; // assumes an 8x8 font rectangle (0, 0, len, 16); settextjustify (LEFT_TEXT, TOP_TEXT); outtextxy (0, 4, s); + isize = imagesize (0, 0, len, 16); + image = malloc (isize); // no checks, come on... + getimage (0, 0, len, 16, image); setlinestyle (SOLID_LINE, 0, THICK_WIDTH); - // while (!kbhit ()) { + int + tmp; + while (1) { + + // we use mouseclick () because we want to check for + // all mouse events; ismouseclick () is much faster + mclick = mouseclick (); - p = mouseclick (); + if (0 == mclick) + continue; - if (p > 0) { - - if ( (mousex () < len) && (mousey () < 16)) - break; + // top left box + if (mousex () < len && mousey () < 16 && + WM_LBUTTONDOWN == mclick) + break; + + switch (mclick) { - if (WM_MOUSEMOVE == p) - putpixel (mousex (), mousey (), getcolor ()); - else { // mouse clicks - setfillstyle (1, // random(WHITE)); - COLOR (random(255), random(255), random(255))); - setcolor (COLOR (random(255), random(255), random(255))); - if (0 == random (2)) - fillellipse (mousex (), mousey (), - 5 + p*random(15), 5 + p*random(15)); - else - bar (mousex () - p*10, mousey () - p*10, - mousex () + p*10, mousey () + p*10); - } // else - } + case WM_MOUSEMOVE: + putpixel (mousex (), mousey (), getcolor ()); + break; + + // double click - draw an X + case WM_LBUTTONDBLCLK: + case WM_MBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: + tmp = 10 + random (40); + setcolor (COLOR (random(255), random(255), random(255))); + line (mousex () - tmp, mousey () - tmp, + mousex () + tmp, mousey () + tmp); + line (mousex () + tmp, mousey () - tmp, + mousex () - tmp, mousey () + tmp); + break; + + // mouse release - draw a + + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + tmp = 10 + random (40); + setcolor (COLOR (random(255), random(255), random(255))); + line (mousex (), mousey () - tmp, + mousex (), mousey () + tmp); + line (mousex () - tmp, mousey (), + mousex () + tmp, mousey ()); + break; + + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_WHEELUP: + case WM_WHEELDOWN: + setfillstyle (1, COLOR (random(255), random(255), random(255))); + setcolor (COLOR (random(255), random(255), random(255))); + if (0 == random (2)) + fillellipse (mousex (), mousey (), + 10 + mclick*random(40), + 10 + mclick*random(40)); + else + bar (mousex () - mclick*10, mousey () - mclick*10, + mousex () + mclick*10, mousey () + mclick*10); + break; + + default: + ; + } // switch (mclick) + + putimage (0, 0, image, COPY_PUT); + } // while - + closegraph (); return 0; - + } // main () // ----- end of file mousetest.c - diff --git a/test/multiwin.c b/test/multiwin.c index 84cf77a..830860a 100644 --- a/test/multiwin.c +++ b/test/multiwin.c @@ -38,7 +38,7 @@ int main (int argc, char *argv[]) printf ("Current window: %d\n", win1); x = getmaxx () - 110; y = getmaxy () - 60; - readimagefile ("logo.bmp", x, y, x + 100, y + 50); + readimagefile ("./logo.bmp", x, y, x + 100, y + 50); getevent (); delay (500); @@ -50,7 +50,7 @@ int main (int argc, char *argv[]) circle (100, 100, 50); win2 = getcurrentwindow (); printf ("Current window: %d\n", win2); - readimagefile ("logo.bmp", x, y, x + 100, y + 50); + readimagefile ("./logo.bmp", x, y, x + 100, y + 50); getevent (); delay (500); @@ -64,7 +64,7 @@ int main (int argc, char *argv[]) printf ("Current window: %d\n", win3); x = getmaxx () - 110; y = getmaxy () - 60; - readimagefile ("logo.bmp", x, y, x + 100, y + 50); + readimagefile ("./logo.bmp", x, y, x + 100, y + 50); getevent (); delay (500); @@ -73,8 +73,10 @@ int main (int argc, char *argv[]) circle (150, 100, 50); win1 = getcurrentwindow (); printf ("Current window: %d\n", win1); + setcolor (YELLOW); outtextxy (0, 10, "Back to the FIRST window; press a key"); getevent (); + setcolor (RED); outtextxy (0, 20, "Shutting down..."); setwintitle (win3, "Window 3 is shutting down..."); diff --git a/test/pdj.c b/test/pdj.c new file mode 100644 index 0000000..e8e85df --- /dev/null +++ b/test/pdj.c @@ -0,0 +1,124 @@ +/* pdj.c -*- C -*- + * + * To compile: + * gcc -o pdj pdj.c -lSDL_bgi -lSDL2 -lm + * + * By Guido Gonzato, February 2022. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include + +// ----- + +void create_palette (void) +{ + int x; + + // blue fading to white + for (x = 0; x < 256; x++) + setrgbpalette (x, x, x, 255); // end at 255,255,255 + + // white fading to red + for (x = 0; x < 256; x++) + setrgbpalette (x + 256, 255, 255 - x, 255 - x); // end at 255,0,0 + + // red fading to purple + for (x = 0; x < 256; x++) + setrgbpalette (x + 512, 255, 0, x); // end at 255,0,255 + + // purple fading to blue + for (x = 0; x < 256; x++) + setrgbpalette (x + 768, 255 - x, 0, 255); // end at 0,0,255 + +} // create_palette () + +// ----- + +int main (int argc, char **argv) +{ + + float + a = 1.641, + b = 1.902, + c = 0.316, + d = 1.525, + x = 0.0, + y = 0.0, + xx, yy; + + int + color, + stop = SDL_FALSE, + xm, ym, ly; + + unsigned long cnt = 0; + + initwindow (800, 600); + create_palette (); + xm = getmaxx () / 2; + ym = getmaxy () / 2; + ly = ym / 2; + srand (time (NULL)); + printf ("a = %7.4f, b = %7.4f, c = %7.4f, d = %7.4f\n", + a, b, c, d); + + while (! stop) { + + xx = sinf (a * y) - cosf (b * x); + yy = sinf (c * x) - cosf (d * y); + + color = cnt / 16384; + if (color > 1024) + cnt = color = 0; + setrgbcolor (color); + _putpixel (xm + ly * xx, ym + ly * yy); + x = xx; + y = yy; + + if (0 == cnt++ % 5000) { + + refresh (); + + if (WM_LBUTTONDOWN == mouseclick ()) { + a = -4.0 + 8 * random (10000) / 10000.0; + b = -4.0 + 8 * random (10000) / 10000.0; + c = -4.0 + 8 * random (10000) / 10000.0; + d = -4.0 + 8 * random (10000) / 10000.0; + printf ("a = %7.4f, b = %7.4f, c = %7.4f, d = %7.4f\n", + a, b, c, d); + cleardevice (); + } + + if (kbhit ()) { + stop = SDL_TRUE; + break; + } + + } // if (0 == cnt++ % 5000) + + } // while + + getch (); + closegraph (); + +} + +// ----- end of file pdj.c diff --git a/test/plasma.bmp b/test/plasma.bmp index 06fde3a..4b33a8b 100644 Binary files a/test/plasma.bmp and b/test/plasma.bmp differ diff --git a/test/plasma.c b/test/plasma.c index ab7a7a3..a3369ed 100644 --- a/test/plasma.c +++ b/test/plasma.c @@ -78,4 +78,4 @@ int main (int argc, char *argv[]) } -// end of file plasma.c +// ----- end of file plasma.c diff --git a/test/psychedelia.c b/test/psychedelia.c index 617abf3..292ce17 100644 --- a/test/psychedelia.c +++ b/test/psychedelia.c @@ -69,11 +69,11 @@ int main (int argc, char **argv) showinfobox ("Left click to switch between\n" "putbuffer() and putpixel();\n" - "any key to stop."); + "right click to stop."); int time = SDL_GetTicks (); - while (! xkbhit()) { + while (! ismouseclick (WM_RBUTTONDOWN)) { int maxx = getmaxx (), @@ -131,7 +131,7 @@ int main (int argc, char **argv) if (k3 < 2 || k3 > 255) d3 *= -1; - if (1 == mouseclick()) { + if (WM_LBUTTONDOWN == mouseclick()) { use_buffer ^= 1; if (use_buffer) puts ("Using putbuffer()"); diff --git a/test/rgbpalette.c b/test/rgbpalette.c index d47ecf1..8c61d9e 100644 --- a/test/rgbpalette.c +++ b/test/rgbpalette.c @@ -58,7 +58,7 @@ int main (int argc, char *argv[]) setrgbcolor (i); setfillstyle (SOLID_FILL, RGBPALETTE (i)); bar (10, 10, 200, 200); - delay (50); + delay (20); } // save the ARGB palette @@ -68,9 +68,9 @@ int main (int argc, char *argv[]) getrgbpalette (&palette, MAX); cleardevice (); - // reset ARGB colours to dark gray + // reset ARGB colours to gray for (i = 0; i < MAX; i++) - setrgbpalette (i, 30, 30, 30); + setrgbpalette (i, 128, 128, 128); setcolor (WHITE); outtextxy (250, 100, "Grayed out ARGB colours..."); @@ -78,7 +78,7 @@ int main (int argc, char *argv[]) setrgbcolor (i); setfillstyle (SOLID_FILL, RGBPALETTE (i)); bar (10, 10, 200, 200); - delay (50); + delay (20); } // restore the ARGB palette @@ -94,7 +94,7 @@ int main (int argc, char *argv[]) setrgbcolor (i); setfillstyle (SOLID_FILL, RGBPALETTE (i)); bar (10, 10, 200, 200); - delay (50); + delay (20); } setcolor (WHITE); outtextxy (250, 120, "Press a key to exit"); diff --git a/test/sdlbgidemo.c b/test/sdlbgidemo.c index 2b48cb6..be1074e 100644 --- a/test/sdlbgidemo.c +++ b/test/sdlbgidemo.c @@ -3,7 +3,7 @@ * To compile: * gcc -o sdlbgidemo sdlbgidemo.c -lSDL_bgi -lSDL2 -lm * - * By Guido Gonzato, 2018 - 2020 + * By Guido Gonzato, 2018-2022 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,71 +29,39 @@ int maxx, maxy, width, height; -int gd, gm; - struct viewporttype viewport; -void pause1 (int); void get_click (void); +void leave (void); void ket_key (void); -void pause2 (void); +void pause (void); void init_sdlbgi (void); void message (char *str); void mainwindow (void); // ----- -void pause1 (int msec) -{ - int stop = 0; - Uint32 - ticks, - now = SDL_GetTicks (); - - while (! stop) { - if (kbhit ()) - stop = 1; - - ticks = SDL_GetTicks (); - if (ticks - now > msec) - stop = 1; - } - -} // pause1 () - -// ----- - void get_click (void) { - // wait for a mouse click - while (! ismouseclick (WM_LBUTTONDOWN)) - ; + + if (WM_RBUTTONDOWN == getclick ()) + leave (); +#ifndef __EMSCRIPTEN__ while (ismouseclick (WM_LBUTTONDOWN)) ; - +#endif + } // get_click () // ----- -void pause2 (void) +void leave (void) { - // pause and exit if right click - int - stop = 0; - while (! stop) { - if (ismouseclick (WM_LBUTTONDOWN)) - stop = 1; - if (ismouseclick (WM_RBUTTONDOWN)) { - closegraph (); - exit (1); - } - } + closegraph (); + exit (1); - while (ismouseclick (WM_LBUTTONDOWN)) - ; - -} // pause2 () +} // leave () // ----- @@ -104,9 +72,7 @@ void init_sdlbgi (void) SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOW_FULLSCREEN); - detectgraph (&gd, &gm); - initgraph (&gd, &gm, ""); - // initwindow (0, 0); + initwindow (0, 0); sdlbgifast (); maxx = getmaxx (); maxy = getmaxy (); @@ -175,7 +141,7 @@ void load_logo () SDL_WINDOW_BORDERLESS); initwindow (440, 150); readimagefile ("logo.bmp", 0, 0, 440, 150); - pause1 (2000); + delay (2000); closewindow (0); } @@ -217,6 +183,7 @@ void sdlbgi_info (void) gettextsettings (&textinfo); // text style info getpalette (&palette ); driver = getdrivername (); + int gm = 0; mode = getmodename (gm); x = width / 2; // screen centre @@ -251,29 +218,10 @@ void sdlbgi_info (void) outtextxy (x, y += dy, str); sprintf (str, "%s", viewport.clip ? "ON" : "OFF"); outtextxy (x, y += dy, str); - - // we can't use XXX_VALUE on standard colours! - // sprintf (str, "0x%02X%02X%02X", - // RED_VALUE (getbkcolor ()), - // GREEN_VALUE (getbkcolor ()), - // BLUE_VALUE (getbkcolor ())); - sprintf (str, "%d", getcolor ()); outtextxy (x, y += dy, str); - - // sprintf (str, "0x%02X%02X%02X", - // RED_VALUE (getcolor ()), - // GREEN_VALUE (getcolor ()), - // BLUE_VALUE (getcolor ())); - sprintf (str, "%d", getbkcolor ()); outtextxy (x, y += dy, str); - - // sprintf (str, "0x%02X%02X%02X", - // RED_VALUE (fillinfo.color), - // GREEN_VALUE (fillinfo.color), - // BLUE_VALUE (fillinfo.color)); - sprintf (str, "%d", fillinfo.color); outtextxy (x, y += dy, str); sprintf (str, "%d", textinfo.charsize); @@ -284,80 +232,12 @@ void sdlbgi_info (void) outtextxy (x, y += dy, str); refresh (); - pause2 (); + get_click (); } // sdlbgi_info () // ----- -void modedemo () -{ - int - dx, y, size; - void - *m; - - message ("Plotting Bitwise Operators Demonstration"); - mainwindow (); - getviewsettings (&viewport); - dx = (viewport.right - viewport.left - 100) / 5; - y = (viewport.bottom - viewport.top) / 3; - - /* draw a red rectangle and store it */ - settextjustify (LEFT_TEXT, TOP_TEXT); - setfillstyle (SOLID_FILL, RED); - bar (50, y, 50 + dx - 10, y + dx - 10); - size = imagesize (50, y, 50 + dx - 10, y + dx - 10); - m = malloc (size); - getimage (50, y, 50 + dx - 10, y + dx - 10, m); - - /* draw five yellow rectangles */ - setcolor (WHITE); - setfillstyle (SOLID_FILL, YELLOW); - for (int i = 0 ; i < 5; i++) - bar (50 + i*dx, y, 50 + i*dx + dx - 10, y + dx - 10); - - outtextxy (50 + 0*dx, y - 20, "COPY_PUT"); - outtextxy (50 + 1*dx, y - 20, "XOR_PUT"); - outtextxy (50 + 2*dx, y - 20, "OR_PUT"); - outtextxy (50 + 3*dx, y - 20, "AND_PUT"); - outtextxy (50 + 4*dx, y - 20, "NOT_PUT"); - setcolor (BLACK); - - outtextxy (60, y + 10, "ffff00 (yellow)"); - - // COPY_PUT: red: ff0000 - putimage (50 + 0*dx, y + dx/2, m, COPY_PUT); - outtextxy (60 + 0*dx, y + dx/2 + 20, "ff0000"); - outtextxy (60 + 0*dx, y + dx/2 + 30, "(red)"); - - // XOR_PUT: red xor yellow: ff0000 ^ ffff00 = 00ff00 (green) - putimage (50 + 1*dx, y + dx/2, m, XOR_PUT); - outtextxy (60 + 1*dx, y + dx/2 + 20, "ff0000 ^ ffff00 = 00ff00"); - outtextxy (60 + 1*dx, y + dx/2 + 30, "(green)"); - - // OR_PUT: red or yellow: ff0000 | ffff00 = ffff00 (yellow) - putimage (50 + 2*dx, y + dx/2, m, OR_PUT); - outtextxy (60 + 2*dx, y + dx/2 + 20, "ff0000 | ffff00 = ffff00"); - outtextxy (60 + 2*dx, y + dx/2 + 30, "(yellow)"); - - // AND_PUT: red and yellow: ff0000 & ffff00 = ff0000 (red) - putimage (50 + 3*dx, y + dx/2, m, AND_PUT); - outtextxy (60 + 3*dx, y + dx/2 + 20, "ff0000 & ffff00 = 00ff00"); - outtextxy (60 + 3*dx, y + dx/2 + 30, "(red)"); - - // NOT_PUT: ~ red: 00ffff (cyan) - putimage (50 + 4*dx, y + dx/2, m, NOT_PUT); - outtextxy (60 + 4*dx, y + dx/2 + 20, "~ ff0000 = 00ffff"); - outtextxy (60 + 4*dx, y + dx/2 + 30, "(cyan)"); - - refresh (); - pause2 (); - -} // modedemo () - -// ----- - void colordemo (void) { // show RGB colours @@ -380,29 +260,25 @@ void colordemo (void) for (col3 = 0; col3 < 256; col3++) { setcolor (COLOR (col1, col2, col3)); - // draw lines + // draw line for (i = 0; i < 3; i++) { line (x, y - maxy / 3, x, y + maxy / 3); x++; } - if (ismouseclick (WM_RBUTTONDOWN)) { - closegraph (); - exit (1); - } + if (ismouseclick (WM_RBUTTONDOWN)) + leave (); } // for refresh (); x = (viewport.right - viewport.left) / 2 - (256 * 3) / 2; - delay (100); - if (ismouseclick (WM_LBUTTONDOWN)) stop = 1; - if (ismouseclick (WM_RBUTTONDOWN)) { - closegraph (); - exit (1); - } + if (ismouseclick (WM_RBUTTONDOWN)) + leave (); + + delay (100); } // while @@ -437,10 +313,8 @@ void pixeldemo (void) if (ismouseclick (WM_LBUTTONDOWN)) stop = 1; - if (ismouseclick (WM_RBUTTONDOWN)) { - closegraph (); - exit (1); - } + if (ismouseclick (WM_RBUTTONDOWN)) + leave (); } // while @@ -493,10 +367,8 @@ void linedemo (void) if (ismouseclick (WM_LBUTTONDOWN)) stop = 1; - if (ismouseclick (WM_RBUTTONDOWN)) { - closegraph (); - exit (1); - } + if (ismouseclick (WM_RBUTTONDOWN)) + leave (); } // while @@ -572,10 +444,8 @@ void linereldemo (void) if (ismouseclick (WM_LBUTTONDOWN)) stop = 1; - if (ismouseclick (WM_RBUTTONDOWN)) { - closegraph (); - exit (1); - } + if (ismouseclick (WM_RBUTTONDOWN)) + leave (); } // while @@ -618,10 +488,8 @@ void boxdemo (void) if (ismouseclick (WM_LBUTTONDOWN)) stop = 1; - if (ismouseclick (WM_RBUTTONDOWN)) { - closegraph (); - exit (1); - } + if (ismouseclick (WM_RBUTTONDOWN)) + leave (); } // while @@ -667,10 +535,8 @@ void polygondemo (void) if (ismouseclick (WM_LBUTTONDOWN)) stop = 1; - if (ismouseclick (WM_RBUTTONDOWN)) { - closegraph (); - exit (1); - } + if (ismouseclick (WM_RBUTTONDOWN)) + leave (); } // while @@ -724,10 +590,8 @@ void circledemo (void) if (ismouseclick (WM_LBUTTONDOWN)) stop = 1; - if (ismouseclick (WM_RBUTTONDOWN)) { - closegraph (); - exit (1); - } + if (ismouseclick (WM_RBUTTONDOWN)) + leave (); } // while @@ -764,10 +628,8 @@ void ellipsedemo (void) if (ismouseclick (WM_LBUTTONDOWN)) stop = 1; - if (ismouseclick (WM_RBUTTONDOWN)) { - closegraph (); - exit (1); - } + if (ismouseclick (WM_RBUTTONDOWN)) + leave (); } // while @@ -937,15 +799,13 @@ void floodfilldemo (void) if (ismouseclick (WM_LBUTTONDOWN)) stop = 1; - if (ismouseclick (WM_RBUTTONDOWN)) { - closegraph (); - exit (1); - } + if (ismouseclick (WM_RBUTTONDOWN)) + leave (); } // while refresh (); - pause2 (); + get_click (); } // floodfilldemo () @@ -977,10 +837,8 @@ void alphademo (void) if (ismouseclick (WM_LBUTTONDOWN)) stop = 1; - if (ismouseclick (WM_RBUTTONDOWN)) { - closegraph (); - exit (1); - } + if (ismouseclick (WM_RBUTTONDOWN)) + leave (); } // while @@ -1016,10 +874,8 @@ void readimagedemo (void) if (ismouseclick (WM_LBUTTONDOWN)) stop = 1; - if (ismouseclick (WM_RBUTTONDOWN)) { - closegraph (); - exit (1); - } + if (ismouseclick (WM_RBUTTONDOWN)) + leave (); } // while @@ -1103,8 +959,7 @@ void putimagedemo (void) if (ismouseclick (WM_RBUTTONDOWN)) { free (image); - closegraph (); - exit (1); + leave (); } } // while @@ -1177,10 +1032,8 @@ void sdlmixdemo (void) } if (ismouseclick (WM_LBUTTONDOWN)) stop = 1; - if (ismouseclick (WM_RBUTTONDOWN)) { - closegraph (); - exit (1); - } + if (ismouseclick (WM_RBUTTONDOWN)) + leave (); } // while @@ -1225,7 +1078,7 @@ void textdemo (void) outtextxy (xm, ym, "RIGHT_TEXT, TOP_TEXT"); refresh (); - pause2 (); + get_click (); clearviewport (); setcolor (RED); @@ -1251,7 +1104,7 @@ void textdemo (void) outtextxy (xm, ym, "RIGHT_TEXT, TOP_TEXT"); refresh (); - pause2 (); + get_click (); clearviewport (); setcolor (RED); @@ -1289,7 +1142,7 @@ void pagedemo (void) char title [100]; - message ("setactivepage() / setvisualpage () Demonstration"); + message ("setactivepage() / setvisualpage() Demonstration"); mainwindow (); getviewsettings (&viewport); @@ -1315,7 +1168,7 @@ void pagedemo (void) for (num_page = 0; num_page < VPAGES; num_page++) { setvisualpage (num_page); refresh (); - pause2 (); + get_click (); } setactivepage (0); @@ -1324,7 +1177,7 @@ void pagedemo (void) outtextxy (xm, ym + 60, "Welcome back to page #0!"); refresh (); - pause2 (); + get_click (); } // pagedemo () @@ -1369,21 +1222,17 @@ void theend (void) outtextxy (xm + 1, ym + 1, "That's all, folks!"); outtextxy (xm - 1, ym - 1, "That's all, folks!"); refresh (); - if (ismouseclick (WM_RBUTTONDOWN)) { - closegraph (); - exit (1); - } + if (ismouseclick (WM_RBUTTONDOWN)) + leave (); } delay (500); if (ismouseclick (WM_LBUTTONDOWN)) stop = 1; - if (ismouseclick (WM_RBUTTONDOWN)) { - closegraph (); - exit (1); - } - + if (ismouseclick (WM_RBUTTONDOWN)) + leave (); + } // while refresh (); @@ -1395,11 +1244,11 @@ void theend (void) int main (int argc, char *argv[]) { + load_logo (); init_sdlbgi (); sdlbgi_info (); - // modedemo (); colordemo (); pixeldemo (); linedemo (); @@ -1416,6 +1265,9 @@ int main (int argc, char *argv[]) textdemo (); pagedemo (); theend (); - + // winclose (); return 0; + } + +// ----- end of file sdlbgidemo.c diff --git a/test/shells/canvas_only.html b/test/shells/canvas_only.html new file mode 100644 index 0000000..e96f3bb --- /dev/null +++ b/test/shells/canvas_only.html @@ -0,0 +1,96 @@ + + + + + + Emscripten-Generated Code + + + +
Downloading...
+
+ +
+
+ +
+ + + {{{ SCRIPT }}} + + diff --git a/test/shells/fullwindow.html b/test/shells/fullwindow.html new file mode 100644 index 0000000..ef3a334 --- /dev/null +++ b/test/shells/fullwindow.html @@ -0,0 +1,100 @@ + + + + + + Emscripten-Generated Code + + + +
Downloading...
+
+ +
+
+ +
+ + + {{{ SCRIPT }}} + + diff --git a/test/shells/sdl_bgi.html b/test/shells/sdl_bgi.html new file mode 100644 index 0000000..2013eeb --- /dev/null +++ b/test/shells/sdl_bgi.html @@ -0,0 +1,135 @@ + + + + + + Emscripten-Generated Code + + + +
emscripten
+
Downloading...
+
+ +
+
+ +
+ + + + + {{{ SCRIPT }}} + + diff --git a/test/shells/shell_minimal.html b/test/shells/shell_minimal.html new file mode 100644 index 0000000..8088b32 --- /dev/null +++ b/test/shells/shell_minimal.html @@ -0,0 +1,145 @@ + + + + + + Emscripten-Generated Code + + + +
+
emscripten
+
Downloading...
+
+ +
+
+ +
+
+
+ Resize canvas + Lock/hide mouse pointer +     + +
+ +
+ +
+ + {{{ SCRIPT }}} + + diff --git a/test/simple.c b/test/simple.c index a2005ff..fe571af 100644 --- a/test/simple.c +++ b/test/simple.c @@ -27,7 +27,7 @@ int i, stop, maxx, maxy; -int pause (int msec) +int _pause (int msec) { // like delay(), but takes care of keypresses @@ -43,7 +43,7 @@ int pause (int msec) return keypressed; -} // pause () +} // _pause () // ----- @@ -77,7 +77,7 @@ void circles (void) circle (random (maxx), random(maxy), random (100)); } refresh (); - stop = pause (1000); + stop = _pause (1000); cleardevice (); } // while @@ -98,7 +98,7 @@ void lines (void) line (random(maxx), random(maxy), random(maxx), random(maxy)); } refresh (); - stop = pause (1000); + stop = _pause (1000); cleardevice (); } // while @@ -120,7 +120,7 @@ void pixels (void) putpixel (random(maxx), random(maxy), col); } refresh (); - stop = pause (1000); + stop = _pause (1000); if (stop) break; srand (2015); @@ -129,7 +129,7 @@ void pixels (void) putpixel (random(maxx), random(maxy), BLACK); } refresh (); - stop = pause (1000); + stop = _pause (1000); cleardevice (); } // while diff --git a/test/tccrun b/test/tccrun new file mode 100644 index 0000000..3ebba97 --- /dev/null +++ b/test/tccrun @@ -0,0 +1,28 @@ +#!/bin/sh + +if [ $(uname) != "Linux" ] ; then + echo "Sorry, GNU/Linux only!" + exit 1 +fi + +if ! [ -x "$(command -v tcc)" ] ; then + echo "Error: 'tcc' could not be found." >&2 + exit 1 +fi + +MYSELF=$(basename $0) + +if [ $# -eq 0 ] ; then + printf "Usage: ${MYSELF} [arguments]\n" + exit 1 +fi + +PROGRAM=$1 +shift +ARGS=$@ +# you may have to extend this variable to include "-lSDL2_image" +SDL_BGI_OPTS="-I /usr/include/SDL2 -lSDL_bgi -lSDL2" +TCC_OPTS="-w -D SDL_DISABLE_IMMINTRIN_H" +tcc -run $TCC_OPTS $SDL_BGI_OPTS $PROGRAM $ARGS + +# --- end of file tccrun diff --git a/test/turtledemo.c b/test/turtledemo.c index b69201b..9771ffd 100644 --- a/test/turtledemo.c +++ b/test/turtledemo.c @@ -308,13 +308,14 @@ int powerof2 (int ex) int main (int argc, char *argv[]) { - int i, l, x, y, xc, stop = 0; + int + i, l, x, y, xc, stop = 0; char s[200]; - initwindow (1024, 768); + initwindow (0, 0); setbkcolor (BLACK); setcolor (GREEN); - + turtle_hello (); pause (); @@ -350,7 +351,7 @@ int main (int argc, char *argv[]) cleardevice (); setcolor (GREEN); outtextxy (0, 0, "Square Koch curve:"); - setposition (0, getmaxy () / 2); + setposition (0, getmaxy () * 0.66); setheading (T_EAST); setcolor (i + 1); sq_koch (getmaxx () + 1, i); diff --git a/tmp/README.md b/tmp/README.md index e5b4c23..e943a0e 100644 --- a/tmp/README.md +++ b/tmp/README.md @@ -9,5 +9,7 @@ These are helper programs: - `dumpchar.c` is used to dump VGA characters used by Turbo C 2.01 in DosBox. +- `icon.c` writes the `icon.bmp` icon, later converted to PNG. + - `truncate.c` shows a bug in Turbo C 2.01; text is not truncated out of the viewport as it should be. This bug is fixed in Turbo C++ 3. diff --git a/tmp/icon.c b/tmp/icon.c new file mode 100644 index 0000000..3726fac --- /dev/null +++ b/tmp/icon.c @@ -0,0 +1,26 @@ +#include + +int main (int argc, int *argv[]) +{ + SDL_Surface *surface; + + initwindow (256, 256); + cleardevice (); + settextstyle (TRIPLEX_FONT, HORIZ_DIR, 10); + setcolor (BLUE); + outtextxy (22, 10, "SDL"); + outtextxy (23, 10, "SDL"); + outtextxy (22, 11, "SDL"); + outtextxy (23, 11, "SDL"); + setcolor (RED); + outtextxy (32, 80, "BGI"); + outtextxy (33, 80, "BGI"); + outtextxy (32, 81, "BGI"); + outtextxy (33, 81, "BGI"); + refresh (); + surface = SDL_GetWindowSurface (bgi_window); + SDL_SaveBMP (surface, "icon.bmp"); + + getch (); + closegraph (); +} \ No newline at end of file diff --git a/tmp/sdl_bgi.spec b/tmp/sdl_bgi.spec new file mode 100644 index 0000000..dce805f --- /dev/null +++ b/tmp/sdl_bgi.spec @@ -0,0 +1,66 @@ +# sdl_bgi.spec - tested on Fedora 34 + +%global debug_package %{nil} + +Summary: SDL2-based 'GRAPHICS.H' implementation +Name: SDL_bgi +Version: 2.6.0 +Release: 1 +License: ZLib +Group: Libraries +Source: %{name}-%{version}.tar.gz +URL: http://sdl_bgi.sourceforge.net/ +BuildRequires: SDL2-devel +Prefix: %{_prefix} +BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot + +%description +SDL_bgi is a Borland Graphics Interface ('GRAPHICS.H') implementation +based on SDL2. This library strictly emulates BGI functions, making it +possible to compile SDL2 versions of programs written for Turbo +C/Borland C++. ARGB colours, vector fonts, mouse support, and multiple +windows are also implemented; further, native SDL2 functions may be +used in SDL_bgi programs. SDL_bgi also supports Wasm via Emscripten. + +%prep +%setup -q -n %{name}-%{version} + +%build +cd src +make + +%install +rm -rf $RPM_BUILD_ROOT +cd src +mkdir -p $RPM_BUILD_ROOT/%{_libdir} +mkdir -p $RPM_BUILD_ROOT/%{_includedir} +mkdir -p $RPM_BUILD_ROOT/%{_includedir}/SDL2/ +mkdir -p $RPM_BUILD_ROOT/%{_mandir}/man3/ +/usr/bin/install -m 644 graphics.h $RPM_BUILD_ROOT/%{_includedir} +/usr/bin/install -m 644 SDL_bgi.h $RPM_BUILD_ROOT/%{_includedir}/SDL2/ +/usr/bin/install -m 644 lib%{name}.so $RPM_BUILD_ROOT/%{_libdir} +cd ../doc/ +/usr/bin/install -m 644 graphics.3.gz $RPM_BUILD_ROOT/%{_mandir}/man3/ + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(644,root,root,755) +%doc AUTHORS BUGS ChangeLog doc/ INSTALL_Emscripten.md +%doc INSTALL_Linux.md INSTALL_Windows.md INSTALL_macOS.md +%doc LICENSE README.md sdl_bgi.spec test/ TODO VERSION +%attr(644,root,root) %{_libdir}/lib%{name}.so +%attr(644,root,root) %{_includedir}/SDL2/SDL_bgi.h +%attr(644,root,root) %{_includedir}/graphics.h +%attr(644,root,root) %{_mandir}/man3/graphics.3.gz + +%changelog +* Tue Jan 2 2018 Guido Gonzato +Slightly improved portability. + +* Sun Oct 22 2017 Guido Gonzato +Slightly improved portability. + +* Thu Nov 6 2014 Guido Gonzato +This is a generic rpm, also buildable on Ubuntu