MODULE showcase_rectangles ; (* m2SDL3 showcase, ported from SDL upstream examples/renderer/05-rectangles/rectangles.c (public domain). Draws animated rectangle outlines, a filled rectangle and a bar chart every frame; sizes breathe in and out over 2 seconds. SDL3 native form: - SDL_RenderRect/Rects/FillRect/FillRects take SDL_FRect (SHORTREAL fields); integer sizes are converted with VAL(SHORTREAL, VAL(REAL, ...)). - Rect arrays pass as ADR(rects) + count (see SDL3Render). - Callback structure flattened into a main loop; auto-quit after 8 s so the showcase also terminates unattended. *) FROM SYSTEM IMPORT ADDRESS, ADR, 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_RenderRect, SDL_RenderRects, SDL_RenderFillRect, SDL_RenderFillRects; FROM SDL3Rect IMPORT SDLFRect, MakeFRect; FROM SDL3Utils IMPORT DrainEvents; FROM libc IMPORT printf; CONST FrameMs = 16; MaxMs = 8000; CONST WinW = 640; WinH = 480; VAR win: WindowHandle; ren: RendererHandle; rects: ARRAY [0..15] OF SDLFRect; quit: BOOLEAN; start: LONGCARD; now: LONGCARD; dir, sm, i, size, w, h: INTEGER; PROCEDURE F (v: INTEGER) : SHORTREAL; BEGIN RETURN VAL(SHORTREAL, VAL(REAL, v)) END F; BEGIN IF NOT SDL_Init(SDLInitVideo) THEN printf("showcase_rectangles: SDL_Init failed\n"); HALT(1) END; IF NOT SDL_CreateWindowAndRenderer("m2SDL3 rectangles", WinW, WinH, VAL(LONGCARD, WindowResizable), win, ren) THEN printf("showcase_rectangles: CreateWindowAndRenderer failed\n"); SDL_Quit; HALT(1) END; SDL_SetRenderLogicalPresentation(ren, WinW, WinH, LogicalLetterbox); printf("showcase_rectangles: close window or wait 8s\n"); quit := FALSE; start := SDL_GetTicks(); WHILE NOT quit DO DrainEvents(quit); now := SDL_GetTicks(); (* breathe: +1 for one second, -1 for the next. *) IF VAL(INTEGER, now MOD 2000) >= 1000 THEN dir := 1 ELSE dir := -1 END; (* scale in permille, -500..500. *) sm := (VAL(INTEGER, now MOD 1000) - 500) * dir; SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, 0), VAL(CARDINAL8, 0), VAL(CARDINAL8, 0), VAL(CARDINAL8, 255)); SDL_RenderClear(ren); (* single outlined square, top left. *) rects[0] := MakeFRect(F(100), F(100), F(100 + 100 * sm DIV 500), F(100 + 100 * sm DIV 500)); SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, 255), VAL(CARDINAL8, 0), VAL(CARDINAL8, 0), VAL(CARDINAL8, 255)); SDL_RenderRect(ren, rects[0]); (* three centered outlines at once. *) FOR i := 0 TO 2 DO size := (i + 1) * 50; w := size + size * sm DIV 500; rects[i] := MakeFRect(F((WinW - w) DIV 2), F((WinH - w) DIV 2), F(w), F(w)) END; SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, 0), VAL(CARDINAL8, 255), VAL(CARDINAL8, 0), VAL(CARDINAL8, 255)); SDL_RenderRects(ren, ADR(rects), 3); (* one filled rectangle. *) rects[0] := MakeFRect(F(400), F(50), F(100 + 100 * sm DIV 500), F(50 + 50 * sm DIV 500)); SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, 0), VAL(CARDINAL8, 0), VAL(CARDINAL8, 255), VAL(CARDINAL8, 255)); SDL_RenderFillRect(ren, rects[0]); (* white bar chart along the bottom. *) FOR i := 0 TO 15 DO w := WinW DIV 16; h := i * 8; rects[i] := MakeFRect(F(i * w), F(WinH - h), F(w), F(h)) END; SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, 255), VAL(CARDINAL8, 255), VAL(CARDINAL8, 255), VAL(CARDINAL8, 255)); SDL_RenderFillRects(ren, ADR(rects), 16); 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_rectangles: bye\n") END showcase_rectangles.