Here's how you can compile and run C programs in Engine BASIC (works with H3 and SDL):
- Write some C code. (The required header files have been included in the H3 image for a while now.)
- Compile it with
TCC "<file>.c"
- Repeat 2 if you have more than one file that you want to link.
- Link the code with
TCCLINK "<module name>"
.
If your program contains a main()
function, EB will now have created a wrapper that makes it easy to call it from BASIC. Say you linked your program with TCCLINK "myprogram"
. You can then run it with |myprogram
(note the pipe symbol) without arguments, or with arguments like so: |myprogram "one", "two", "three"
.
If your program did not contain a main()
function, no wrapper will be created. In either case you can call any global symbol in it using the symbol's name. That also applies to all API functions exported by the system. (See https://github.com/uli/basicengine-firmware/blob/nextgen/ttbasic/export_syms.h for a list.)
It is possible to get return values from C functions by using them like an expression:
wurzel=|sqrt#(#2)
Note that you have to tell BASIC the correct type for both return value (the first #
, meaning double
) and arguments (the second #
, also double
). Other types are !
(float
) and *
(pointer). Numeric arguments without a type sigil are passed as int
. If an argument is a string, it will be passed as a char *
.
To allocate some memory, use:
ptr=|malloc*(42)
This will allocate 42 bytes and put the pointer in ptr. You can free it again with
|free *ptr
Please be aware that C APIs do not usually waste resources on stuff like input validation. If you use them the wrong way, your system will crash. If you're unlucky, it will take your data with it. Use all of this with caution.
As a practical example of what this can do, I have added a new demo to the demo repo called playmod
. It takes the pocketmod library and adds a 50-line wrapper (playmod.c
) that allows you to use |playmod "space_debris.mod"
and |stopmod
to play/stop MOD files from BASIC. (Note that this required a tiny bit of extra infrastructure (eb_get_mixer()
) and a bug fix, so it will only work with the next build...)
Have a nice weekend!