SDL3 Gnu Modula-2 binding (basic only but works)

Eric Streit ec6be4244d feat: system-info bindings batch 2 viikkoa sitten
docs ec6be4244d feat: system-info bindings batch 2 viikkoa sitten
examples ed80b57626 feat: SDL3 bindings for GNU Modula-2, starter set 2 viikkoa sitten
lib ed80b57626 feat: SDL3 bindings for GNU Modula-2, starter set 2 viikkoa sitten
showcases ed80b57626 feat: SDL3 bindings for GNU Modula-2, starter set 2 viikkoa sitten
src ec6be4244d feat: system-info bindings batch 2 viikkoa sitten
tests ec6be4244d feat: system-info bindings batch 2 viikkoa sitten
.gitignore ed80b57626 feat: SDL3 bindings for GNU Modula-2, starter set 2 viikkoa sitten
Makefile ec6be4244d feat: system-info bindings batch 2 viikkoa sitten
README.md ec6be4244d feat: system-info bindings batch 2 viikkoa sitten

README.md

m2SDL3 — SDL3 bindings for GNU Modula-2

Thin DEFINITION MODULE FOR "C" bindings of SDL 3.4 for gm2 (GCC 16 / GNU Modula-2), covering init, video, version, timer, error, events and the 2D renderer starter subset.

Upstream sources live in SDL-release-3.4.16/ (read-only reference, never modified by this binding; per its AGENTS.md no AI-generated code is contributed upstream). All binding code below is original work that only uses SDL headers at compile time and links the prebuilt SDL-release-3.4.16/build/libSDL3.so.

Status

Starter set, verified with gm2 + SDL 3.4.16 on Linux:

Module C header Contents
SDL3 <SDL3/SDL_init.h>, <SDL3/SDL_error.h>, <SDL3/SDL_timer.h> init/quit (BOOLEAN returns), GetError, Delay/DelayNS, 64-bit ticks, performance counter
SDL3Version <SDL3/SDL_version.h> SDL_GetVersion(): INTEGER versionnum, GetRevision
SDL3Video <SDL3/SDL_video.h> window create/destroy, title, size/position, show/hide, flags (LONGCARD)
SDL3Events <SDL3/SDL_events.h> PumpEvents, PollEvent, WaitEvent, WaitEventTimeout, PushEvent, HasEvent(s) (BOOLEAN), quit/key/mouse + window-close constants, 128-byte buffer
SDL3Rect <SDL3/SDL_rect.h> pure-M2 SDLPoint/SDLFPoint/SDLRect/SDLFRect + helpers (SHORTREAL = C float)
SDL3Render <SDL3/SDL_render.h> window+renderer creation, draw color (+float), logical presentation, clear/present, points/lines/rects (float SDLFRect), render scale, output size, debug text
SDL3Key <SDL3/SDL_keycode.h> pure-M2 keycode constants (arrows, Q/R, Escape...)
SDL3Stdinc <SDL3/SDL_stdinc.h> malloc/calloc/free (frees SDL-allocated strings)
SDL3Filesystem <SDL3/SDL_filesystem.h> base/pref/user-folder/cwd paths, mkdir/remove/rename/copy (no callbacks)
SDL3Power <SDL3/SDL_power.h> GetPowerInfo state + seconds/percent
SDL3Locale <SDL3/SDL_locale.h> preferred-locales list (SDLLocale records)
SDL3Clipboard <SDL3/SDL_clipboard.h> plain-text set/get/has (+primary selection; no MIME callbacks)
SDL3Utils (lib/) — CStrToM2() + GetErrorString(), version decode, DrainEvents() quit pump (QUIT + WINDOW_CLOSE_REQUESTED), PollM2Event() decoded poll (keycode at offset 28)

Layout

m2SDL3/
  src/        FOR "C" .def bindings (+ pure-M2 SDL3Rect/SDL3Key)
  lib/        pure-M2 helpers built on the bindings (SDL3Utils)
  tests/      gm2 smoke tests + run_tests.sh
  examples/   hello_window, version, event_loop, renderer_demo
  showcases/  clear, primitives, lines, points, rectangles, debug_text, snake
  build/      generated binaries (git-ignored)
  SDL-release-3.4.16/  upstream SDL reference + prebuilt lib (untouched)

Prerequisites

  • gm2 (tested: 16.0.1 experimental, ~/bin/Modula2/Gm2/bin/gm2)
  • SDL 3.4.16 already built at SDL-release-3.4.16/build/libSDL3.so (headers at SDL-release-3.4.16/include)
export PATH=$HOME/bin/Modula2/Gm2/bin:$PATH

Build & test

make            # tests + examples + showcases -> build/
./tests/run_tests.sh
SDL_VIDEODRIVER=dummy ./tests/run_tests.sh   # headless
./build/examples/hello_window
./build/examples/version
./build/examples/event_loop
./build/examples/renderer_demo
./build/showcases/showcase_clear   # or rectangles / primitives / snake

make check is make tests + the runner script.

Usage

FROM SDL3 IMPORT SDL_Init, SDL_Quit, SDLInitVideo;
FROM SDL3Video IMPORT SDL_CreateWindow, SDL_DestroyWindow, WindowHidden;

Compile your program with the binding search path and the C library:

gm2 -Isrc -Ilib \
  -ISDL-release-3.4.16/include \
  myprog.mod src/SDL3Rect.mod lib/SDL3Utils.mod src/SDL3Key.mod \
  -o myprog -LSDL-release-3.4.16/build -lSDL3 \
  -Wl,-rpath,$PWD/SDL-release-3.4.16/build

Notes:

  • SDL3 bool <-> BOOLEAN (see gm2 "Elementary data types" node); init/video/event/render calls return [ BOOLEAN ] (ignorable): IF NOT SDL_Init(...) THEN or SDL_RenderClear(ren);.
  • CARDINAL <-> Uint32, LONGCARD <-> Uint64, INTEGER <-> int (window flags are 64-bit: pass VAL(LONGCARD, WindowResizable)).
  • SHORTREAL <-> float (SDL_FRect/SDL_FPoint fields, draw coordinates, SetRenderDrawColorFloat); REAL <-> double.
  • Opaque SDL_Window * / SDL_Renderer * / char * travel as ADDRESS (NIL == failure / default driver).
  • ARRAY OF CHAR parameters map onto char *: string literals and CHAR arrays can be passed directly (see gm2 "Interface to C" node).
  • VAR record parameters map onto T *: SDL_GetWindowSize(win,w,h), SDL_RenderFillRect(ren, rect).
  • SDL_GetTicks() is now LONGCARD milliseconds; SDL_GetVersion() returns an INTEGER versionnum (VersionMajor/Minor/Micro decode it).
  • Closing a window yields EventWindowCloseRequested (0210H) as well as EventQuit; DrainEvents/PollM2Event treat both as evQuit.

SDL2 -> SDL3 porting cheatsheet

SDL2 binding SDL3 binding
SDL_Init(): INTEGER, rc # 0 SDL_Init(): [ BOOLEAN ], NOT ... / = FALSE
CreateWindow(t,x,y,w,h,flags: CARDINAL) CreateWindow(t,w,h,flags: LONGCARD)
GetTicks(): CARDINAL + GetTicks64() GetTicks(): LONGCARD (ms), GetTicksNS() (ns)
GetVersion(VAR v) record GetVersion(): INTEGER + VersionMajor/Minor/Micro
RenderDrawPoint/Line/Rect (int) RenderPoint/Line/Rect (SHORTREAL/SDLFRect)
RenderSetLogicalSize(w,h) SetRenderLogicalPresentation(w,h,mode)
EventBufferBytes = 56, sym at 20 EventBufferBytes = 128, key at 28, close-request = quit

Roadmap

  1. Texture/surface subset (SDL_Texture, SDL_Surface load/blit).
  2. Audio stream subset (SDL_AudioStream, device open).
  3. Gamepad/joystick subset.
  4. Full SDL_Event variant record (keyboard/mouse/window typed).