MODULE showcase_debug_text ; (* m2SDL3 showcase, ported from SDL upstream examples/renderer/18-debug-text/debug-text.c (public domain). Renders built-in bitmap debug text: plain lines, a colored line, a 4x-scaled line and a live "running for N seconds" counter. Porting notes - SDL_RenderDebugTextFormat (C varargs) has no Modula-2 mapping, so the counter line is composed into a CHAR buffer with the local AppendCard helper instead. - The upstream emoji line is ASCII-only in SDL anyway; the emoji bytes are replaced by plain words here (CHAR literals stay 8-bit clean this way). - Callback structure flattened into a main loop; auto-quit after 8 s so the showcase also terminates unattended. *) FROM SYSTEM IMPORT CARDINAL8; FROM SDL3 IMPORT SDL_Init, SDL_Quit, SDL_Delay, SDL_GetTicks, SDLInitVideo; FROM SDL3Video IMPORT WindowHandle, SDL_DestroyWindow, WindowResizable; FROM SDL3Render IMPORT RendererHandle, SDL_CreateWindowAndRenderer, SDL_DestroyRenderer, SDL_SetRenderDrawColor, SDL_RenderClear, SDL_RenderPresent, SDL_SetRenderLogicalPresentation, LogicalLetterbox, SDL_SetRenderScale, SDL_RenderDebugText; FROM SDL3Utils IMPORT DrainEvents; FROM libc IMPORT printf; CONST FrameMs = 16; MaxMs = 8000; CONST WinW = 640; WinH = 480; VAR win: WindowHandle; ren: RendererHandle; quit: BOOLEAN; start: LONGCARD; secs: LONGCARD; pos: CARDINAL; msg: ARRAY [0..127] OF CHAR; (* Append decimal n at buf[pos]; RETURN new pos (buf stays NUL-ended). *) PROCEDURE AppendCard (VAR buf: ARRAY OF CHAR; pos: CARDINAL; n: LONGCARD) : CARDINAL; VAR digits: ARRAY [0..23] OF CHAR; nd, k: CARDINAL; BEGIN nd := 0; IF n = 0 THEN digits[0] := "0"; nd := 1 ELSE WHILE n > 0 DO digits[nd] := CHR(ORD("0") + VAL(CARDINAL, n MOD 10)); INC(nd); n := n DIV 10 END END; k := nd; WHILE k > 0 DO DEC(k); IF pos <= HIGH(buf) THEN buf[pos] := digits[k]; INC(pos) END END; IF pos <= HIGH(buf) THEN buf[pos] := 0C END; RETURN pos END AppendCard; PROCEDURE AppendStr (VAR buf: ARRAY OF CHAR; pos: CARDINAL; s: ARRAY OF CHAR) : CARDINAL; VAR k: CARDINAL; BEGIN k := 0; WHILE (k <= HIGH(s)) AND (s[k] # 0C) DO IF pos <= HIGH(buf) THEN buf[pos] := s[k]; INC(pos) END; INC(k) END; IF pos <= HIGH(buf) THEN buf[pos] := 0C END; RETURN pos END AppendStr; BEGIN IF NOT SDL_Init(SDLInitVideo) THEN printf("showcase_debug_text: SDL_Init failed\n"); HALT(1) END; IF NOT SDL_CreateWindowAndRenderer("m2SDL3 debug text", WinW, WinH, VAL(LONGCARD, WindowResizable), win, ren) THEN printf("showcase_debug_text: CreateWindowAndRenderer failed\n"); SDL_Quit; HALT(1) END; SDL_SetRenderLogicalPresentation(ren, WinW, WinH, LogicalLetterbox); printf("showcase_debug_text: close window or wait 8s\n"); quit := FALSE; start := SDL_GetTicks(); WHILE NOT quit DO DrainEvents(quit); SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, 0), VAL(CARDINAL8, 0), VAL(CARDINAL8, 0), VAL(CARDINAL8, 255)); SDL_RenderClear(ren); SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, 255), VAL(CARDINAL8, 255), VAL(CARDINAL8, 255), VAL(CARDINAL8, 255)); SDL_RenderDebugText(ren, VAL(SHORTREAL, 272.0), VAL(SHORTREAL, 100.0), "Hello world!"); SDL_RenderDebugText(ren, VAL(SHORTREAL, 224.0), VAL(SHORTREAL, 150.0), "This is some debug text."); SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, 51), VAL(CARDINAL8, 102), VAL(CARDINAL8, 255), VAL(CARDINAL8, 255)); SDL_RenderDebugText(ren, VAL(SHORTREAL, 184.0), VAL(SHORTREAL, 200.0), "You can do it in different colors."); SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, 255), VAL(CARDINAL8, 255), VAL(CARDINAL8, 255), VAL(CARDINAL8, 255)); SDL_SetRenderScale(ren, VAL(SHORTREAL, 4.0), VAL(SHORTREAL, 4.0)); SDL_RenderDebugText(ren, VAL(SHORTREAL, 14.0), VAL(SHORTREAL, 65.0), "It can be scaled."); SDL_SetRenderScale(ren, VAL(SHORTREAL, 1.0), VAL(SHORTREAL, 1.0)); SDL_RenderDebugText(ren, VAL(SHORTREAL, 64.0), VAL(SHORTREAL, 350.0), "This only does ASCII chars."); secs := (SDL_GetTicks() - start) DIV 1000; pos := AppendStr(msg, 0, "(This program has been running for "); pos := AppendCard(msg, pos, secs); pos := AppendStr(msg, pos, " seconds.)"); SDL_RenderDebugText(ren, VAL(SHORTREAL, 136.0), VAL(SHORTREAL, 400.0), msg); SDL_RenderPresent(ren); IF SDL_GetTicks() - start > MaxMs THEN quit := TRUE END; SDL_Delay(FrameMs) END; SDL_DestroyRenderer(ren); SDL_DestroyWindow(win); SDL_Quit; printf("showcase_debug_text: bye\n") END showcase_debug_text.