MODULE showcase_points ; (* m2SDL3 showcase, ported from SDL upstream examples/renderer/04-points/points.c (public domain). 500 white points drift down-right at 30..60 px/s; points that leave the screen respawn at the top or left edge. Porting notes - SDL_randf() becomes (rand() MOD 10000) / 10000.0 with libc rand. - Positions/speeds live in parallel arrays so the whole set goes to SDL_RenderPoints in one call, as in the C version. - 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_RenderPoints; FROM SDL3Rect IMPORT SDLFPoint, MakeFPoint; FROM SDL3Utils IMPORT DrainEvents; FROM libc IMPORT printf, rand, srand; CONST FrameMs = 16; MaxMs = 8000; CONST WinW = 640; WinH = 480; NPoints = 500; CONST MinSpeed = 30.0; MaxSpeed = 60.0; VAR win: WindowHandle; ren: RendererHandle; points: ARRAY [0..NPoints-1] OF SDLFPoint; speeds: ARRAY [0..NPoints-1] OF REAL; quit: BOOLEAN; start, last, now: LONGCARD; elapsed: REAL; i: INTEGER; (* Random REAL in [0.0, 1.0). *) PROCEDURE RandF () : REAL; BEGIN RETURN VAL(REAL, rand() MOD 10000) / 10000.0 END RandF; PROCEDURE RandSpeed () : REAL; BEGIN RETURN MinSpeed + RandF() * (MaxSpeed - MinSpeed) END RandSpeed; BEGIN IF NOT SDL_Init(SDLInitVideo) THEN printf("showcase_points: SDL_Init failed\n"); HALT(1) END; IF NOT SDL_CreateWindowAndRenderer("m2SDL3 points", WinW, WinH, VAL(LONGCARD, WindowResizable), win, ren) THEN printf("showcase_points: CreateWindowAndRenderer failed\n"); SDL_Quit; HALT(1) END; SDL_SetRenderLogicalPresentation(ren, WinW, WinH, LogicalLetterbox); srand(VAL(INTEGER, SDL_GetTicks())); FOR i := 0 TO NPoints - 1 DO points[i] := MakeFPoint(VAL(SHORTREAL, RandF() * VAL(REAL, WinW)), VAL(SHORTREAL, RandF() * VAL(REAL, WinH))); speeds[i] := RandSpeed() END; printf("showcase_points: close window or wait 8s\n"); quit := FALSE; start := SDL_GetTicks(); last := start; WHILE NOT quit DO DrainEvents(quit); now := SDL_GetTicks(); elapsed := VAL(REAL, now - last) / 1000.0; last := now; FOR i := 0 TO NPoints - 1 DO points[i].x := VAL(SHORTREAL, VAL(REAL, points[i].x) + elapsed * speeds[i]); points[i].y := VAL(SHORTREAL, VAL(REAL, points[i].y) + elapsed * speeds[i]); IF (VAL(REAL, points[i].x) >= VAL(REAL, WinW)) OR (VAL(REAL, points[i].y) >= VAL(REAL, WinH)) THEN IF rand() MOD 2 = 0 THEN points[i].x := VAL(SHORTREAL, RandF() * VAL(REAL, WinW)); points[i].y := VAL(SHORTREAL, 0.0) ELSE points[i].x := VAL(SHORTREAL, 0.0); points[i].y := VAL(SHORTREAL, RandF() * VAL(REAL, WinH)) END; speeds[i] := RandSpeed() END END; 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_RenderPoints(ren, ADR(points), NPoints); SDL_RenderPresent(ren); IF now - start > MaxMs THEN quit := TRUE END; SDL_Delay(FrameMs) END; SDL_DestroyRenderer(ren); SDL_DestroyWindow(win); SDL_Quit; printf("showcase_points: bye\n") END showcase_points.