Bläddra i källkod

feat: renderer binding plus SDL-main showcases

- src/SDLRender.def: SDL2 render subset (create window+renderer,
  draw color, clear/present, points/lines/rects, logical size)
- lib/SDLUtils: DrainEvents quit pump shared by showcases
- showcases: clear, rectangles, primitives ported from
  SDL-main examples/renderer (01, 05, 02), SDL3->SDL2 noted
- Makefile: showcases target; README updated
Eric Streit 2 veckor sedan
förälder
incheckning
31c9a29aba
9 ändrade filer med 475 tillägg och 5 borttagningar
  1. 11 2
      Makefile
  2. 5 2
      README.md
  3. 5 1
      lib/SDLUtils.def
  4. 15 0
      lib/SDLUtils.mod
  5. 24 0
      showcases/README.md
  6. 79 0
      showcases/showcase_clear.mod
  7. 103 0
      showcases/showcase_primitives.mod
  8. 117 0
      showcases/showcase_rectangles.mod
  9. 116 0
      src/SDLRender.def

+ 11 - 2
Makefile

@@ -14,10 +14,11 @@ INCLUDES := -I$(SRC_DIR) -I$(LIB_DIR)
 
 TESTS    := test_init test_version test_rect test_window
 EXAMPLES := hello_window version event_loop
+SHOWCASES := showcase_clear showcase_rectangles showcase_primitives
 
-.PHONY: all tests examples clean check
+.PHONY: all tests examples showcases clean check
 
-all: tests examples
+all: tests examples showcases
 
 $(OBJDIR):
 	mkdir -p $(OBJDIR)
@@ -44,6 +45,14 @@ examples: $(BLD)/examples $(OBJS) $(addprefix $(BLD)/examples/,$(EXAMPLES))
 $(BLD)/examples/%: examples/%.mod $(OBJS) | $(BLD)/examples
 	$(GM2) $(INCLUDES) $(GM2FLAGS) $(SDLCONF) $< $(OBJS) -o $@ $(SDLLIBS)
 
+$(BLD)/showcases:
+	mkdir -p $(BLD)/showcases
+
+showcases: $(BLD)/showcases $(OBJS) $(addprefix $(BLD)/showcases/,$(SHOWCASES))
+
+$(BLD)/showcases/%: showcases/%.mod $(OBJS) | $(BLD)/showcases
+	$(GM2) $(INCLUDES) $(GM2FLAGS) $(SDLCONF) $< $(OBJS) -o $@ $(SDLLIBS)
+
 check: tests
 	./tests/run_tests.sh
 

+ 5 - 2
README.md

@@ -15,7 +15,8 @@ Starter set, verified with gm2 + SDL 2.32.4 on Linux:
 | `SDLVideo` | `<SDL_video.h>` | window create/destroy, title, size, show/hide |
 | `SDLEvents` | `<SDL_events.h>` | `PumpEvents`, `PollEvent`, `WaitEvent`, quit/key/mouse type ids (opaque buffer for now) |
 | `SDLRect` | `<SDL_rect.h>` | pure-M2 `SDLPoint`/`SDLRect` + helpers |
-| `SDLUtils` (`lib/`) | — | `CStrToM2()` + `GetErrorString()` helpers |
+| `SDLRender` | `<SDL_render.h>` | window+renderer creation, draw color, clear/present, points/lines/rects |
+| `SDLUtils` (`lib/`) | — | `CStrToM2()` + `GetErrorString()` helpers, `DrainEvents()` quit pump |
 
 Full `SDL_Event` union mapping, renderer, audio and gamepad come next.
 
@@ -27,6 +28,7 @@ m2SDL/
   lib/        pure-M2 helpers built on the bindings (SDLUtils)
   tests/      gm2 smoke tests + run_tests.sh
   examples/   hello_window, version, event_loop
+  showcases/  ports of SDL-main renderer examples (clear, rectangles, primitives)
   build/      generated binaries (git-ignored)
 ```
 
@@ -42,12 +44,13 @@ export PATH=$HOME/bin/Modula2/Gm2/bin:$PATH
 ## Build & test
 
 ```sh
-make            # tests + examples -> build/
+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/showcases/showcase_clear   # or rectangles / primitives
 ```
 
 `make check` is `make tests` + the runner script.

+ 5 - 1
lib/SDLUtils.def

@@ -4,13 +4,17 @@ DEFINITION MODULE SDLUtils ;
    m2SDL - small pure-Modula-2 helpers over the FOR "C" bindings.
    Copies NUL-terminated C strings (ADDRESS) into Modula-2 CHAR
    arrays (NUL-terminated, truncated to the destination length).
+   DrainEvents pumps the queue and reports whether a quit event
+   was seen; event type is the leading Uint32 of SDL_Event, read
+   little-endian (matches x86/x86-64/ARM hosts).
 *)
 
 FROM SYSTEM IMPORT ADDRESS;
 
-EXPORT UNQUALIFIED CStrToM2, GetErrorString;
+EXPORT UNQUALIFIED CStrToM2, GetErrorString, DrainEvents;
 
 PROCEDURE CStrToM2 (src: ADDRESS; VAR dst: ARRAY OF CHAR);
 PROCEDURE GetErrorString (VAR buf: ARRAY OF CHAR);
+PROCEDURE DrainEvents (VAR quit: BOOLEAN);
 
 END SDLUtils.

+ 15 - 0
lib/SDLUtils.mod

@@ -2,6 +2,7 @@ IMPLEMENTATION MODULE SDLUtils ;
 
 FROM SYSTEM IMPORT ADDRESS, ADR;
 FROM SDL2 IMPORT SDL_GetError;
+FROM SDLEvents IMPORT SDL_PollEvent, EventQuit, EventBufferBytes;
 FROM libc IMPORT strlen, strncpy;
 
 PROCEDURE CStrToM2 (src: ADDRESS; VAR dst: ARRAY OF CHAR);
@@ -21,4 +22,18 @@ BEGIN
    CStrToM2(SDL_GetError(), buf)
 END GetErrorString;
 
+PROCEDURE DrainEvents (VAR quit: BOOLEAN);
+VAR
+   buf: ARRAY [0..EventBufferBytes-1] OF CHAR;
+   t: CARDINAL;
+BEGIN
+   WHILE SDL_PollEvent(ADR(buf)) # 0 DO
+      t := VAL(CARDINAL, ORD(buf[0]))
+         + VAL(CARDINAL, ORD(buf[1])) * 256
+         + VAL(CARDINAL, ORD(buf[2])) * 65536
+         + VAL(CARDINAL, ORD(buf[3])) * 16777216;
+      IF t = EventQuit THEN quit := TRUE END
+   END
+END DrainEvents;
+
 END SDLUtils.

+ 24 - 0
showcases/README.md

@@ -0,0 +1,24 @@
+# m2SDL showcases
+
+Ports of example programs from the vendored SDL archive (`SDL-main/`,
+ignored by git) to GNU Modula-2, running against SDL2.
+
+| Showcase | Ported from | Shows |
+|---|---|---|
+| `showcase_clear` | `examples/renderer/01-clear/clear.c` | renderer, per-frame clear color, `MathLib0.sin` fade |
+| `showcase_rectangles` | `examples/renderer/05-rectangles/rectangles.c` | draw/fill rects, rect arrays via `ADR`, integer scale math |
+| `showcase_primitives` | `examples/renderer/02-primitives/primitives.c` | fill rect, point cloud (`libc rand`), outline, X lines |
+
+All three are public-domain originals; adaptation notes (SDL3 to SDL2
+API renames, float to integer rects, callback to main-loop shape) live
+in each file header.
+
+Build and run:
+
+```sh
+make showcases
+./build/showcases/showcase_clear       # close window, or waits 8 s
+./build/showcases/showcase_rectangles
+./build/showcases/showcase_primitives
+SDL_VIDEODRIVER=dummy ./build/showcases/showcase_clear   # headless
+```

+ 79 - 0
showcases/showcase_clear.mod

@@ -0,0 +1,79 @@
+MODULE showcase_clear ;
+
+(*
+   m2SDL showcase, ported from SDL-main
+   examples/renderer/01-clear/clear.c (public domain).
+
+   Clears the window to a smoothly fading color every frame; the
+   sine-wave trick picks the color from the elapsed time.
+
+   SDL3 -> SDL2 adaptations
+   - SDL_CreateWindowAndRenderer keeps the SDL2 (w, h, flags,
+     win^, ren^) form; SDL_WINDOW_RESIZABLE reused as-is.
+   - SDL_SetRenderDrawColorFloat does not exist in SDL2, so the
+     0.0..1.0 floats are scaled to Uint8 0..255 here.
+   - Callback structure (SDL_AppInit/Iterate/...) is flattened
+     into a plain main loop with DrainEvents; auto-quit after 8 s
+     so the showcase also terminates unattended.
+*)
+
+FROM SYSTEM IMPORT CARDINAL8;
+FROM SDL2 IMPORT SDL_Init, SDL_Quit, SDL_Delay,
+   SDL_GetTicks, SDL_GetTicks64, SDLInitVideo;
+FROM SDLVideo IMPORT WindowHandle, SDL_DestroyWindow, WindowResizable;
+FROM SDLRender IMPORT RendererHandle,
+   SDL_CreateWindowAndRenderer, SDL_DestroyRenderer,
+   SDL_SetRenderDrawColor, SDL_RenderClear, SDL_RenderPresent,
+   SDL_RenderSetLogicalSize;
+FROM SDLUtils IMPORT DrainEvents;
+FROM MathLib0 IMPORT sin, entier;
+FROM libc IMPORT printf;
+
+CONST FrameMs = 16; MaxMs = 8000;
+
+VAR
+   win: WindowHandle;
+   ren: RendererHandle;
+   quit: BOOLEAN;
+   start: LONGCARD;
+   t: REAL;
+   r, g, b: INTEGER;
+
+BEGIN
+   IF SDL_Init(SDLInitVideo) # 0 THEN
+      printf("showcase_clear: SDL_Init failed\n");
+      HALT(1)
+   END;
+   IF SDL_CreateWindowAndRenderer(640, 480, WindowResizable,
+                                  win, ren) # 0 THEN
+      printf("showcase_clear: CreateWindowAndRenderer failed\n");
+      SDL_Quit;
+      HALT(1)
+   END;
+   SDL_RenderSetLogicalSize(ren, 640, 480);
+
+   printf("showcase_clear: fading, close window or wait 8s\n");
+   quit := FALSE;
+   start := SDL_GetTicks64();
+   WHILE NOT quit DO
+      DrainEvents(quit);
+      (* seconds since start, as REAL (double). *)
+      t := VAL(REAL, SDL_GetTicks()) / 1000.0;
+      r := entier(127.5 + 127.5 * sin(t));
+      g := entier(127.5 + 127.5 * sin(t + 2.0944));
+      b := entier(127.5 + 127.5 * sin(t + 4.1888));
+      SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, r),
+                             VAL(CARDINAL8, g),
+                             VAL(CARDINAL8, b),
+                             VAL(CARDINAL8, 255));
+      SDL_RenderClear(ren);
+      SDL_RenderPresent(ren);
+      IF SDL_GetTicks64() - start > MaxMs THEN quit := TRUE END;
+      SDL_Delay(FrameMs)
+   END;
+
+   SDL_DestroyRenderer(ren);
+   SDL_DestroyWindow(win);
+   SDL_Quit;
+   printf("showcase_clear: bye\n")
+END showcase_clear.

+ 103 - 0
showcases/showcase_primitives.mod

@@ -0,0 +1,103 @@
+MODULE showcase_primitives ;
+
+(*
+   m2SDL showcase, ported from SDL-main
+   examples/renderer/02-primitives/primitives.c (public domain).
+
+   Draws a filled rectangle, 500 random points, an inset outline
+   and a yellow X across the canvas every frame.
+
+   SDL3 -> SDL2 adaptations
+   - SDL_RenderRect/RenderPoints become SDL2
+     SDL_RenderDrawRect / SDL_RenderDrawPoints.
+   - SDL_FPoint floats become integer SDLPoint; SDL_randf is
+     replaced by libc rand seeded from SDL_GetTicks.
+   - Point array passes as ADR(points) + count (see SDLRender).
+   - 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 SDL2 IMPORT SDL_Init, SDL_Quit, SDL_Delay,
+   SDL_GetTicks, SDL_GetTicks64, SDLInitVideo;
+FROM SDLVideo IMPORT WindowHandle, SDL_DestroyWindow, WindowResizable;
+FROM SDLRender IMPORT RendererHandle,
+   SDL_CreateWindowAndRenderer, SDL_DestroyRenderer,
+   SDL_SetRenderDrawColor, SDL_RenderClear, SDL_RenderPresent,
+   SDL_RenderSetLogicalSize,
+   SDL_RenderDrawLine, SDL_RenderDrawRect, SDL_RenderDrawPoints,
+   SDL_RenderFillRect;
+FROM SDLRect IMPORT SDLRect, SDLPoint, MakeRect, MakePoint;
+FROM SDLUtils IMPORT DrainEvents;
+FROM libc IMPORT printf, rand, srand;
+
+CONST FrameMs = 16; MaxMs = 8000;
+CONST WinW = 640; WinH = 480; NPoints = 500;
+
+VAR
+   win: WindowHandle;
+   ren: RendererHandle;
+   points: ARRAY [0..NPoints-1] OF SDLPoint;
+   rect: SDLRect;
+   quit: BOOLEAN;
+   start: LONGCARD;
+   i: INTEGER;
+
+BEGIN
+   IF SDL_Init(SDLInitVideo) # 0 THEN
+      printf("showcase_primitives: SDL_Init failed\n");
+      HALT(1)
+   END;
+   IF SDL_CreateWindowAndRenderer(WinW, WinH, WindowResizable,
+                                  win, ren) # 0 THEN
+      printf("showcase_primitives: CreateWindowAndRenderer failed\n");
+      SDL_Quit;
+      HALT(1)
+   END;
+   SDL_RenderSetLogicalSize(ren, WinW, WinH);
+
+   (* scatter the points inside the blue rectangle, as in the C code. *)
+   srand(VAL(INTEGER, SDL_GetTicks()));
+   FOR i := 0 TO NPoints - 1 DO
+      points[i] := MakePoint(rand() MOD 440 + 100, rand() MOD 280 + 100)
+   END;
+
+   printf("showcase_primitives: close window or wait 8s\n");
+   quit := FALSE;
+   start := SDL_GetTicks64();
+   WHILE NOT quit DO
+      DrainEvents(quit);
+
+      SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, 33), VAL(CARDINAL8, 33),
+                             VAL(CARDINAL8, 33), VAL(CARDINAL8, 255));
+      SDL_RenderClear(ren);
+
+      rect := MakeRect(100, 100, 440, 280);
+      SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, 0), VAL(CARDINAL8, 0),
+                             VAL(CARDINAL8, 255), VAL(CARDINAL8, 255));
+      SDL_RenderFillRect(ren, rect);
+
+      SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, 255), VAL(CARDINAL8, 0),
+                             VAL(CARDINAL8, 0), VAL(CARDINAL8, 255));
+      SDL_RenderDrawPoints(ren, ADR(points), NPoints);
+
+      rect := MakeRect(130, 130, 380, 220);
+      SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, 0), VAL(CARDINAL8, 255),
+                             VAL(CARDINAL8, 0), VAL(CARDINAL8, 255));
+      SDL_RenderDrawRect(ren, rect);
+
+      SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, 255), VAL(CARDINAL8, 255),
+                             VAL(CARDINAL8, 0), VAL(CARDINAL8, 255));
+      SDL_RenderDrawLine(ren, 0, 0, WinW, WinH);
+      SDL_RenderDrawLine(ren, 0, WinH, WinW, 0);
+
+      SDL_RenderPresent(ren);
+      IF SDL_GetTicks64() - start > MaxMs THEN quit := TRUE END;
+      SDL_Delay(FrameMs)
+   END;
+
+   SDL_DestroyRenderer(ren);
+   SDL_DestroyWindow(win);
+   SDL_Quit;
+   printf("showcase_primitives: bye\n")
+END showcase_primitives.

+ 117 - 0
showcases/showcase_rectangles.mod

@@ -0,0 +1,117 @@
+MODULE showcase_rectangles ;
+
+(*
+   m2SDL showcase, ported from SDL-main
+   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 -> SDL2 adaptations
+   - SDL_RenderRect/Rects/FillRect/FillRects become the SDL2
+     SDL_RenderDrawRect(s) / SDL_RenderFillRect(s) spellings.
+   - SDL_FRect floats become integer SDLRect; the -1.0..1.0 scale
+     is kept as permille (-500..500) with integer arithmetic.
+   - Rect arrays pass as ADR(rects) + count (see SDLRender docs).
+   - 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 SDL2 IMPORT SDL_Init, SDL_Quit, SDL_Delay,
+   SDL_GetTicks, SDL_GetTicks64, SDLInitVideo;
+FROM SDLVideo IMPORT WindowHandle, SDL_DestroyWindow, WindowResizable;
+FROM SDLRender IMPORT RendererHandle,
+   SDL_CreateWindowAndRenderer, SDL_DestroyRenderer,
+   SDL_SetRenderDrawColor, SDL_RenderClear, SDL_RenderPresent,
+   SDL_RenderSetLogicalSize,
+   SDL_RenderDrawRect, SDL_RenderDrawRects,
+   SDL_RenderFillRect, SDL_RenderFillRects;
+FROM SDLRect IMPORT SDLRect, MakeRect;
+FROM SDLUtils 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 SDLRect;
+   quit: BOOLEAN;
+   start: LONGCARD;
+   now: CARDINAL;
+   dir, sm, i, size, w, h: INTEGER;
+
+BEGIN
+   IF SDL_Init(SDLInitVideo) # 0 THEN
+      printf("showcase_rectangles: SDL_Init failed\n");
+      HALT(1)
+   END;
+   IF SDL_CreateWindowAndRenderer(WinW, WinH, WindowResizable,
+                                  win, ren) # 0 THEN
+      printf("showcase_rectangles: CreateWindowAndRenderer failed\n");
+      SDL_Quit;
+      HALT(1)
+   END;
+   SDL_RenderSetLogicalSize(ren, WinW, WinH);
+
+   printf("showcase_rectangles: close window or wait 8s\n");
+   quit := FALSE;
+   start := SDL_GetTicks64();
+   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] := MakeRect(100, 100, 100 + 100 * sm DIV 500,
+                                    100 + 100 * sm DIV 500);
+      SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, 255), VAL(CARDINAL8, 0),
+                             VAL(CARDINAL8, 0), VAL(CARDINAL8, 255));
+      SDL_RenderDrawRect(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] := MakeRect((WinW - w) DIV 2, (WinH - w) DIV 2, w, w)
+      END;
+      SDL_SetRenderDrawColor(ren, VAL(CARDINAL8, 0), VAL(CARDINAL8, 255),
+                             VAL(CARDINAL8, 0), VAL(CARDINAL8, 255));
+      SDL_RenderDrawRects(ren, ADR(rects), 3);
+
+      (* one filled rectangle. *)
+      rects[0] := MakeRect(400, 50, 100 + 100 * sm DIV 500,
+                                    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] := MakeRect(i * w, WinH - h, w, 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_GetTicks64() - 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.

+ 116 - 0
src/SDLRender.def

@@ -0,0 +1,116 @@
+DEFINITION MODULE FOR "C" SDLRender ;
+
+(*
+   m2SDL - 2D renderer binding (SDL2 <SDL_render.h>), starter subset.
+
+   Opaque handle: SDL_Renderer * travels as ADDRESS (NIL == failure).
+   Single rects pass as VAR SDLRect (GM2 maps VAR record params onto
+   T * ); rect/point arrays pass as ADDRESS of the first element plus
+   a count, e.g. ADR(rects) with rects: ARRAY OF SDLRect.
+
+   Color components are Uint8 in C, hence SYSTEM.CARDINAL8 here -
+   SHORTCARD would be 16 bits and would not match the ABI.
+*)
+
+FROM SYSTEM IMPORT ADDRESS, CARDINAL8;
+FROM SDLRect IMPORT SDLRect;
+FROM SDLVideo IMPORT WindowHandle;
+
+EXPORT UNQUALIFIED
+   RendererHandle,
+   RendererSoftware, RendererAccelerated,
+   RendererPresentVSync, RendererTargetTexture,
+
+   SDL_CreateRenderer, SDL_CreateWindowAndRenderer,
+   SDL_DestroyRenderer,
+   SDL_SetRenderDrawColor, SDL_GetRenderDrawColor,
+   SDL_RenderSetLogicalSize,
+   SDL_RenderClear, SDL_RenderPresent,
+   SDL_RenderDrawPoint, SDL_RenderDrawPoints,
+   SDL_RenderDrawLine, SDL_RenderDrawLines,
+   SDL_RenderDrawRect, SDL_RenderDrawRects,
+   SDL_RenderFillRect, SDL_RenderFillRects;
+
+
+TYPE
+   RendererHandle = ADDRESS;
+
+CONST
+   RendererSoftware      = 000000001H;
+   RendererAccelerated   = 000000002H;
+   RendererPresentVSync  = 000000004H;
+   RendererTargetTexture = 000000008H;
+
+
+(* SDL_Renderer *SDL_CreateRenderer(SDL_Window *win, int index,
+                                    Uint32 flags) *)
+PROCEDURE SDL_CreateRenderer (win: WindowHandle; index: INTEGER;
+                              flags: CARDINAL) : RendererHandle;
+
+(* int SDL_CreateWindowAndRenderer(int w, int h, Uint32 flags,
+                                   SDL_Window **win, SDL_Renderer **ren) *)
+PROCEDURE SDL_CreateWindowAndRenderer (w, h: INTEGER; flags: CARDINAL;
+                                       VAR win: WindowHandle;
+                                       VAR ren: RendererHandle) : [ INTEGER ];
+
+(* void SDL_DestroyRenderer(SDL_Renderer *ren) *)
+PROCEDURE SDL_DestroyRenderer (ren: RendererHandle);
+
+(* int SDL_SetRenderDrawColor(SDL_Renderer *ren,
+                              Uint8 r, Uint8 g, Uint8 b, Uint8 a) *)
+PROCEDURE SDL_SetRenderDrawColor (ren: RendererHandle;
+                                  r, g, b, a: CARDINAL8) : [ INTEGER ];
+
+(* int SDL_GetRenderDrawColor(SDL_Renderer *ren,
+                              Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a) *)
+PROCEDURE SDL_GetRenderDrawColor (ren: RendererHandle;
+                                  VAR r, g, b, a: CARDINAL8) : [ INTEGER ];
+
+(* int SDL_RenderSetLogicalSize(SDL_Renderer *ren, int w, int h) *)
+PROCEDURE SDL_RenderSetLogicalSize (ren: RendererHandle;
+                                    w, h: INTEGER) : [ INTEGER ];
+
+(* int SDL_RenderClear(SDL_Renderer *ren) *)
+PROCEDURE SDL_RenderClear (ren: RendererHandle) : [ INTEGER ];
+
+(* void SDL_RenderPresent(SDL_Renderer *ren) *)
+PROCEDURE SDL_RenderPresent (ren: RendererHandle);
+
+(* int SDL_RenderDrawPoint(SDL_Renderer *ren, int x, int y) *)
+PROCEDURE SDL_RenderDrawPoint (ren: RendererHandle;
+                               x, y: INTEGER) : [ INTEGER ];
+
+(* int SDL_RenderDrawPoints(SDL_Renderer *ren, const SDL_Point *pts,
+                            int count) *)
+PROCEDURE SDL_RenderDrawPoints (ren: RendererHandle; pts: ADDRESS;
+                                count: INTEGER) : [ INTEGER ];
+
+(* int SDL_RenderDrawLine(SDL_Renderer *ren,
+                          int x1, int y1, int x2, int y2) *)
+PROCEDURE SDL_RenderDrawLine (ren: RendererHandle;
+                              x1, y1, x2, y2: INTEGER) : [ INTEGER ];
+
+(* int SDL_RenderDrawLines(SDL_Renderer *ren, const SDL_Point *pts,
+                           int count) *)
+PROCEDURE SDL_RenderDrawLines (ren: RendererHandle; pts: ADDRESS;
+                               count: INTEGER) : [ INTEGER ];
+
+(* int SDL_RenderDrawRect(SDL_Renderer *ren, const SDL_Rect *rect) *)
+PROCEDURE SDL_RenderDrawRect (ren: RendererHandle;
+                              VAR rect: SDLRect) : [ INTEGER ];
+
+(* int SDL_RenderDrawRects(SDL_Renderer *ren, const SDL_Rect *rects,
+                           int count) *)
+PROCEDURE SDL_RenderDrawRects (ren: RendererHandle; rects: ADDRESS;
+                               count: INTEGER) : [ INTEGER ];
+
+(* int SDL_RenderFillRect(SDL_Renderer *ren, const SDL_Rect *rect) *)
+PROCEDURE SDL_RenderFillRect (ren: RendererHandle;
+                              VAR rect: SDLRect) : [ INTEGER ];
+
+(* int SDL_RenderFillRects(SDL_Renderer *ren, const SDL_Rect *rects,
+                           int count) *)
+PROCEDURE SDL_RenderFillRects (ren: RendererHandle; rects: ADDRESS;
+                               count: INTEGER) : [ INTEGER ];
+
+END SDLRender.