IMPLEMENTATION MODULE SDLUtils ; FROM SYSTEM IMPORT ADDRESS, ADR; FROM SDL2 IMPORT SDL_GetError; FROM SDLEvents IMPORT SDL_PollEvent, EventQuit, EventKeyDown, EventKeyUp, EventBufferBytes; FROM libc IMPORT strlen, strncpy; PROCEDURE CStrToM2 (src: ADDRESS; VAR dst: ARRAY OF CHAR); VAR n: CARDINAL; BEGIN IF HIGH(dst) < 0 THEN RETURN END; IF src = NIL THEN dst[0] := 0C; RETURN END; (* strlen returns CSIZE_T; VAL converts without range check. *) n := VAL(CARDINAL, strlen(src)); IF n > HIGH(dst) THEN n := HIGH(dst) END; strncpy(ADR(dst), src, n); IF n <= HIGH(dst) THEN dst[n] := 0C END END CStrToM2; PROCEDURE GetErrorString (VAR buf: ARRAY OF CHAR); BEGIN CStrToM2(SDL_GetError(), buf) END GetErrorString; (* Little-endian 32-bit word at byte offset off. Hosts only. *) PROCEDURE LE32 (VAR buf: ARRAY OF CHAR; off: CARDINAL) : CARDINAL; BEGIN RETURN VAL(CARDINAL, ORD(buf[off])) + VAL(CARDINAL, ORD(buf[off+1])) * 256 + VAL(CARDINAL, ORD(buf[off+2])) * 65536 + VAL(CARDINAL, ORD(buf[off+3])) * 16777216 END LE32; PROCEDURE PollM2Event (VAR ev: M2Event) : BOOLEAN; VAR buf: ARRAY [0..EventBufferBytes-1] OF CHAR; t: CARDINAL; BEGIN IF SDL_PollEvent(ADR(buf)) = 0 THEN RETURN FALSE END; t := LE32(buf, 0); ev.sym := 0; ev.pressed := FALSE; IF t = EventKeyDown THEN ev.kind := evKey; ev.pressed := TRUE; (* Sint32 keysym.sym; game keycodes are all positive. *) ev.sym := VAL(INTEGER, LE32(buf, 20)) ELSIF t = EventKeyUp THEN ev.kind := evKey; ev.pressed := FALSE; ev.sym := VAL(INTEGER, LE32(buf, 20)) ELSIF t = EventQuit THEN ev.kind := evQuit ELSE ev.kind := evOther END; RETURN TRUE END PollM2Event; PROCEDURE DrainEvents (VAR quit: BOOLEAN); VAR ev: M2Event; BEGIN WHILE PollM2Event(ev) DO IF ev.kind = evQuit THEN quit := TRUE END END END DrainEvents; END SDLUtils.