├── LICENSE ├── README.md ├── examples ├── liberation-sans.ttf ├── net_server.nim ├── pong.nim ├── sdl_audio_callback.nim ├── sdl_audiostream.nim ├── sdl_mixer_example.nim ├── sdl_opengl_example.nim └── sdl_skeleton.nim ├── sdl2.nimble └── src ├── sdl2.nim └── sdl2 ├── audio.nim ├── gamecontroller.nim ├── gfx.nim ├── haptic.nim ├── image.nim ├── joystick.nim ├── mixer.nim ├── net.nim ├── private └── keycodes.nim └── ttf.nim /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SDL2 for Nim 2 | This package contains the bindings for SDL2 to Nim. 3 | 4 | # Pre-requisites 5 | You must install the SDL2 C libraries before these Nim bindings can be used. 6 | 7 | ## macOS 8 | 9 | #### Homebrew 10 | If you don't already have Homebrew installed, install it from [the Homebrew site](https://brew.sh/). 11 | 12 | Install the SDL2 C libraries: 13 | 14 | ```bash 15 | brew install sdl2{,_gfx,_image,_mixer,_net,_ttf} 16 | ``` 17 | 18 | #### MacPorts 19 | If you don't already have Macports installed, install it from [the Macports site](https://www.macports.org). 20 | 21 | ```bash 22 | sudo port install libsdl2 libsdl2_gfx libsdl2_image libsdl2_mixer libsdl2_ttf libsdl2_net 23 | ``` 24 | 25 | ## Linux 26 | Install SDL2 development libraries using your distribution's packaging tool of choice. 27 | 28 | ## Windows 29 | Using SDL2 with [mingw-w64](https://mingw-w64.org) environment 30 | * Install [mingw-w64-builds](https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/installer/mingw-w64-install.exe). Check that `x86_64-w64-mingw32\bin\` from the installed mingw toolchain is in your `PATH` variable. 31 | * Download [SDL2 Development Libraries](https://www.libsdl.org/download-2.0.php) for MinGW 32 | * Extract contents of the downloaded archive to your mingw-w64 folder (for example, `SDL2-2.0.12\x86_64-w64-mingw32\` to `mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\x86_64-w64-mingw32\`) 33 | ### Static linking SDL2 34 | Pass the following options to nim on compilation: 35 | `--dynlibOverride:libSDL2 --passL:"-static -lmingw32 -lSDL2main -lSDL2 -mwindows -Wl,--no-undefined -Wl,--dynamicbase -Wl,--nxcompat -Wl,--high-entropy-va -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion -luuid"` 36 | Options for the linker (`--passL:`) except `-static` are taken from `sdl2-config.cmake` which is included in SDL2 Development Libraries. 37 | 38 | # Installation 39 | Add `requires "sdl2"` to your `.nimble` file. 40 | 41 | You can also install manually with `nimble install sdl2` if your project does not yet have a nimble package file. 42 | 43 | For more information on using nimble, consult [the nim documentation](https://nim-lang.org/docs/lib.html#nimble). 44 | 45 | # Documentation 46 | For documentation about SDL2 see [wiki.libsdl.org](https://wiki.libsdl.org/). 47 | -------------------------------------------------------------------------------- /examples/liberation-sans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nim-lang/sdl2/e25c67905142c997a72a52c44c2a9736862894be/examples/liberation-sans.ttf -------------------------------------------------------------------------------- /examples/net_server.nim: -------------------------------------------------------------------------------- 1 | import sdl2/net 2 | 3 | var 4 | local: IpAddress 5 | server: TcpSocket 6 | 7 | if net.init() < 0: 8 | quit($net.getError()) 9 | 10 | if resolveHost(addr local, nil, 2000) < 0: 11 | quit($net.getError()) 12 | 13 | server = tcpOpen(addr local) 14 | if server.isNil: 15 | quit($net.getError()) 16 | 17 | var running = true 18 | while running: 19 | let client = server.accept() 20 | if not client.isNil: 21 | 22 | let remote = client.getPeerAddress() 23 | if remote.isNil: 24 | quit($net.getError()) 25 | else: 26 | echo "Host connected: ", resolveIP(remote) 27 | 28 | var buffer: array[513,char] 29 | let buf = buffer[0].addr 30 | while true: 31 | if client.tcpRecv(buf, 512) > 0: 32 | let s = $cast[cstring](buf) 33 | echo "<< ", s 34 | if s == "exit": 35 | echo "disconnecting.." 36 | break 37 | elif s == "shutdown": 38 | echo "quitting..." 39 | running = false 40 | break 41 | 42 | client.close() 43 | 44 | server.close() 45 | net.quit() 46 | -------------------------------------------------------------------------------- /examples/pong.nim: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | import sdl2 4 | import sdl2/ttf 5 | 6 | const 7 | WindowWidth = 640 8 | WindowHeight = 480 9 | 10 | PaddleWidth = 16 11 | PaddleHeight = 64 12 | PaddleSpeed = 400.0 13 | 14 | BallRadius = 8 15 | 16 | MaxBallComponentSpeed = 1000'f32 17 | 18 | TextWidth = 128 19 | TextHeight = 64 20 | 21 | type 22 | Paddle = ref object 23 | x, y: float32 24 | 25 | Ball = ref object 26 | x, y: float32 27 | vx, vy: float32 28 | 29 | Input {.pure.} = enum 30 | Up, 31 | Down, 32 | None 33 | 34 | Game = ref object 35 | running: bool 36 | 37 | inputs: array[Input, bool] 38 | player, opponent: Paddle 39 | ball: Ball 40 | 41 | scores: tuple[player: uint, opponent: uint] 42 | 43 | proc newPaddle(x: float32): Paddle = 44 | Paddle( 45 | x: x, 46 | y: (WindowHeight + PaddleHeight) / 2, 47 | ) 48 | 49 | proc newBall(): Ball = 50 | Ball( 51 | x: WindowWidth / 2 - BallRadius, 52 | y: WindowHeight / 2 - BallRadius, 53 | vx: (rand(2.0) - 1) * 100, 54 | vy: (rand(2.0) - 1) * 300 55 | ) 56 | 57 | func collision(ball: Ball, paddle: Paddle): bool = 58 | return not ( 59 | ball.x > paddle.x + PaddleWidth or 60 | ball.x + 2 * BallRadius < paddle.x or 61 | ball.y > paddle.y + PaddleHeight or 62 | ball.y + 2 * BallRadius < paddle.y 63 | ) 64 | 65 | proc updatePlayer(g: Game, dt: float32) = 66 | if g.inputs[Input.Up]: 67 | g.player.y -= PaddleSpeed * dt 68 | if g.inputs[Input.Down]: 69 | g.player.y += PaddleSpeed * dt 70 | 71 | if g.player.y < 0: 72 | g.player.y = 0 73 | elif g.player.y + PaddleHeight > WindowHeight: 74 | g.player.y = WindowHeight - PaddleHeight 75 | 76 | proc updateOpponent(g: Game, dt: float32) = 77 | let dist = (g.ball.y + BallRadius) - (g.opponent.y + PaddleHeight / 2) 78 | var dy: float32 79 | 80 | if dist > 0: 81 | dy = min(dist, PaddleSpeed * dt) 82 | elif dist < 0: 83 | dy = max(dist, -PaddleSpeed * dt) 84 | 85 | g.opponent.y += dy 86 | g.opponent.y = max(g.opponent.y, 0) 87 | g.opponent.y = min(g.opponent.y, WindowHeight - PaddleWidth) 88 | 89 | proc bounce(v: var float32) = 90 | v *= -1 91 | 92 | v = max(v, -MaxBallComponentSpeed) 93 | v = min(v, MaxBallComponentSpeed) 94 | 95 | proc speedup(v: var float32) = 96 | v *= (1 + rand(0.5)) 97 | 98 | v = max(v, -MaxBallComponentSpeed) 99 | v = min(v, MaxBallComponentSpeed) 100 | 101 | proc updateBall(g: Game, dt: float32) = 102 | g.ball.x += g.ball.vx * dt 103 | g.ball.y += g.ball.vy * dt 104 | 105 | # bounce on upper and lower borders, add speedup on bounce 106 | if g.ball.y < 0: 107 | g.ball.y = 0 108 | bounce(g.ball.vy) 109 | speedup(g.ball.vx) 110 | elif g.ball.y + 2 * BallRadius > WindowHeight: 111 | g.ball.y = WindowHeight - 2 * BallRadius 112 | bounce(g.ball.vy) 113 | speedup(g.ball.vx) 114 | 115 | # bounce on paddles 116 | if g.ball.collision g.player: 117 | g.ball.x = g.player.x + PaddleWidth 118 | bounce(g.ball.vx) 119 | speedup(g.ball.vy) 120 | elif g.ball.collision g.opponent: 121 | g.ball.x = g.opponent.x - 2 * BallRadius 122 | bounce(g.ball.vx) 123 | speedup(g.ball.vy) 124 | 125 | # opponent scored 126 | if g.ball.x + 2 * BallRadius < 0: 127 | inc g.scores.opponent 128 | g.ball = newBall() 129 | 130 | # player scored 131 | elif g.ball.x > WindowWidth: 132 | inc g.scores.player 133 | g.ball = newBall() 134 | 135 | 136 | proc draw(renderer: RendererPtr, paddle: Paddle) = 137 | renderer.setDrawColor 255, 255, 255, 255 # white 138 | var r = rect( 139 | cint(paddle.x), cint(paddle.y), 140 | cint(PaddleWidth), cint(PaddleHeight) 141 | ) 142 | renderer.fillRect(r) 143 | 144 | proc draw(renderer: RendererPtr, ball: Ball) = 145 | renderer.setDrawColor 255, 255, 255, 255 # white 146 | var r = rect( 147 | cint(ball.x), cint(ball.y), 148 | cint(2 * BallRadius), cint(2 * BallRadius) 149 | ) 150 | renderer.fillRect(r) 151 | 152 | proc drawScores( 153 | renderer: RendererPtr, font: FontPtr, scores: tuple[player: uint, opponent: uint] 154 | ) = 155 | let 156 | color = color(255, 255, 255, 0) 157 | text = $scores.player & " : " & $scores.opponent 158 | surface = ttf.renderTextSolid(font, cstring text, color) 159 | texture = renderer.createTextureFromSurface(surface) 160 | 161 | surface.freeSurface 162 | defer: texture.destroy 163 | 164 | var r = rect( 165 | (WindowWidth - TextWidth) div 2, 166 | 0, 167 | TextWidth, 168 | TextHeight 169 | ) 170 | renderer.copy texture, nil, addr r 171 | 172 | proc newGame(): Game = 173 | Game( 174 | running: true, 175 | player: newPaddle(PaddleWidth), 176 | opponent: newPaddle(WindowWidth - 2 * PaddleWidth), 177 | ball: newBall(), 178 | scores: (0'u, 0'u) 179 | ) 180 | 181 | proc update(g: Game, dt: float32) = 182 | g.updatePlayer dt 183 | g.updateOpponent dt 184 | g.updateBall dt 185 | 186 | proc draw(g: Game, renderer: RendererPtr, font: FontPtr) = 187 | renderer.setDrawColor 0, 0, 0, 255 # black 188 | renderer.clear() 189 | 190 | renderer.draw(g.player) 191 | renderer.draw(g.opponent) 192 | renderer.draw(g.ball) 193 | 194 | renderer.drawScores(font, g.scores) 195 | 196 | renderer.present() 197 | 198 | func toInput(key: Scancode): Input = 199 | case key 200 | of SDL_SCANCODE_UP: Input.Up 201 | of SDL_SCANCODE_DOWN: Input.Down 202 | else: Input.None 203 | 204 | type SDLException = object of Defect 205 | 206 | template sdlFailIf(condition: typed, reason: string) = 207 | if condition: raise SDLException.newException( 208 | reason & ", SDL error " & $getError() 209 | ) 210 | 211 | proc main = 212 | sdlFailIf(not sdl2.init(INIT_VIDEO or INIT_TIMER or INIT_EVENTS)): 213 | "SDL2 initialization failed" 214 | defer: sdl2.quit() 215 | 216 | let window = createWindow( 217 | title = "Pong", 218 | x = SDL_WINDOWPOS_CENTERED, 219 | y = SDL_WINDOWPOS_CENTERED, 220 | w = WindowWidth, 221 | h = WindowHeight, 222 | flags = SDL_WINDOW_SHOWN 223 | ) 224 | 225 | sdlFailIf window.isNil: "window could not be created" 226 | defer: window.destroy() 227 | 228 | let renderer = createRenderer( 229 | window = window, 230 | index = -1, 231 | flags = Renderer_Accelerated or Renderer_PresentVsync or Renderer_TargetTexture 232 | ) 233 | sdlFailIf renderer.isNil: "renderer could not be created" 234 | defer: renderer.destroy() 235 | 236 | sdlFailIf(not ttfInit()): "SDL_TTF initialization failed" 237 | defer: ttfQuit() 238 | 239 | let font = ttf.openFont("liberation-sans.ttf", TextHeight) 240 | sdlFailIf font.isNil: "font could not be created" 241 | 242 | var 243 | running = true 244 | game = newGame() 245 | 246 | dt: float32 247 | 248 | counter: uint64 249 | previousCounter: uint64 250 | 251 | counter = getPerformanceCounter() 252 | 253 | while running: 254 | previousCounter = counter 255 | counter = getPerformanceCounter() 256 | 257 | dt = (counter - previousCounter).float / getPerformanceFrequency().float 258 | 259 | var event = defaultEvent 260 | 261 | while pollEvent(event): 262 | case event.kind 263 | of QuitEvent: 264 | running = false 265 | break 266 | 267 | of KeyDown: 268 | game.inputs[event.key.keysym.scancode.toInput] = true 269 | of KeyUp: 270 | game.inputs[event.key.keysym.scancode.toInput] = false 271 | else: 272 | discard 273 | 274 | game.update(dt) 275 | game.draw(renderer, font) 276 | 277 | main() 278 | -------------------------------------------------------------------------------- /examples/sdl_audio_callback.nim: -------------------------------------------------------------------------------- 1 | # Generate and playback a sine tone 2 | 3 | import sdl2 4 | import sdl2/audio 5 | import math 6 | 7 | # Audio settings requested: 8 | const RQBufferSizeInSamples = 4096 9 | const RQBytesPerSample = 2 # 16 bit PCM 10 | const RQBufferSizeInBytes = RQBufferSizeInSamples * RQBytesPerSample 11 | let SampleRate = 44100 # Hz 12 | 13 | # What tone to generate: 14 | let Frequence = 1000 # Hz 15 | let Volume = 0.1 # [0..1] 16 | 17 | # Current playback position 18 | var x = 0 19 | 20 | # Variables 21 | var obtained: AudioSpec # Actual audio parameters SDL returns 22 | 23 | # Generate a sine wave 24 | let c = float(SampleRate) / float(Frequence) 25 | proc SineAmplitude(): int16 = int16(round(sin(float(x mod int(c)) / c * 2 * PI) * 32767 * Volume)) 26 | 27 | # 3 different callback procedures which do the same thing: 28 | 29 | # Write amplitude direct to hardware buffer 30 | proc AudioCallback_1(userdata: pointer; stream: ptr uint8; len: cint) {.cdecl.} = 31 | for i in 0..int16(obtained.samples)-1: 32 | cast[ptr int16](cast[int](stream) + i * RQBytesPerSample)[] = SineAmplitude() 33 | inc(x) 34 | 35 | proc main() = 36 | # Init audio playback 37 | if init(INIT_AUDIO) != SdlSuccess: 38 | echo("Couldn't initialize SDL\n") 39 | return 40 | var audioSpec: AudioSpec 41 | audioSpec.freq = cint(SampleRate) 42 | audioSpec.format = AUDIO_S16 # 16 bit PCM 43 | audioSpec.channels = 1 # mono 44 | audioSpec.samples = RQBufferSizeInBytes 45 | audioSpec.padding = 0 46 | audioSpec.callback = AudioCallback_1 47 | audioSpec.userdata = nil 48 | if openAudio(addr(audioSpec), addr(obtained)) != 0: 49 | echo("Couldn't open audio device. " & $getError() & "\n") 50 | return 51 | echo("frequency: ", obtained.freq) 52 | echo("format: ", obtained.format) 53 | echo("channels: ", obtained.channels) 54 | echo("samples: ", obtained.samples) 55 | echo("padding: ", obtained.padding) 56 | if obtained.format != AUDIO_S16: 57 | echo("Couldn't open 16-bit audio channel.") 58 | return 59 | # Playback audio for 2 seconds 60 | pauseAudio(0) 61 | delay(2000) 62 | 63 | main() 64 | -------------------------------------------------------------------------------- /examples/sdl_audiostream.nim: -------------------------------------------------------------------------------- 1 | import sdl2, sdl2/audio 2 | 3 | # demonstration of SDL2 audio streams. load in a wav file, use 4 | # an audiostream to convert its encoding to the encoding your 5 | # audio hardware's desired format, then plays that audio by 6 | # queueing it. 7 | 8 | # path of the .wav file to load 9 | const wavFilePath = "example.wav" 10 | 11 | const sampleRate = 48000 12 | const bufferSizeInSamples = 4096 13 | const bytesPerSample = 2 # 16 bit PCM 14 | const nChannels = 1 15 | const bufferSizeInBytes = nChannels * bytesPerSample * bufferSizeInSamples 16 | 17 | proc main() = 18 | # start up SDL2 19 | if sdl2.init(INIT_AUDIO) != SdlSuccess: 20 | quit "failed to init SDL2!" 21 | 22 | # SDL 2.0.7 is the first version with audio streams. If you want 23 | # to convert audio from one format to another before 2.0.7, you 24 | # have to use AudioCVT. 25 | var version: SDL_Version 26 | getVersion(version) 27 | if (version.major <= 2'u8) and 28 | (version.minor <= 0'u8) and 29 | (version.patch < 7'u8): 30 | quit "your version of SDL2 does not support SDL_AudioStream!" 31 | 32 | # ask SDL how many output devices are available 33 | let ndevices = getNumAudioDevices(0.cint).cint 34 | if ndevices == 0: 35 | quit "no devices!" 36 | 37 | # get the name of the first available audio device. this is generally the one you want. 38 | let deviceName = getAudioDeviceName(0.cint, 0.cint) 39 | 40 | # set up the hardware's spec 41 | var hardwareSpec = AudioSpec() 42 | hardwareSpec.freq = sampleRate.cint 43 | hardwareSpec.format = AUDIO_S16 # 16-bit PCM 44 | hardwareSpec.channels = nChannels 45 | hardwareSpec.samples = bufferSizeInBytes 46 | hardwareSpec.padding = 0 47 | 48 | # opening the audio device here. If the device can't handle one of the 49 | # specs we've given it, openAudioDevice will tweak the contents of 50 | # hardwareSpec to match something the device can do. 51 | let deviceId = openAudioDevice(deviceName, 0.cint, addr hardwareSpec, nil, 0) 52 | 53 | echo deviceName 54 | echo " frequency: ", hardwareSpec.freq 55 | echo " format: ", hardwareSpec.format 56 | echo " channels: ", hardwareSpec.channels 57 | echo " samples: ", hardwareSpec.samples 58 | echo " padding: ", hardwareSpec.padding 59 | 60 | # audio devices default to being paused, so turn off pause 61 | deviceId.pauseAudioDevice(0.cint) 62 | 63 | # load in the wav file. wavFileSpec will be filled in with the wav 64 | # file's encoding. 65 | var 66 | wavFileSpec = AudioSpec() 67 | wavBuffer: ptr uint8 68 | wavBufferLen: uint32 69 | 70 | if loadWav(wavFilePath, addr wavFileSpec, addr wavBuffer, addr wavBufferLen).isNil: 71 | echo $sdl2.getError() 72 | quit "failed to load " & wavFilePath 73 | 74 | # make sure to free the buffer before we exit 75 | defer: freeWav(wavBuffer) 76 | 77 | # print some info about the audio specs. 78 | echo "\n", wavFilePath 79 | echo " frequency: ", wavFileSpec.freq 80 | echo " format: ", wavFileSpec.format 81 | echo " channels: ", wavFileSpec.channels 82 | echo " samples: ", wavFileSpec.samples 83 | echo " padding: ", wavFileSpec.padding 84 | 85 | # create a new audio stream that will convert from the wav file's spec, 86 | # to the audio device's spec. 87 | let stream = newAudioStream(wavFileSpec, hardwareSpec) 88 | 89 | # make sure to free the stream before we exit 90 | defer: stream.destroy() 91 | 92 | # put the wav file into the stream 93 | if stream.put(wavBuffer, wavBufferLen.cint) < 0: 94 | echo $sdl2.getError() 95 | quit "failed to put wavBuffer into stream" 96 | 97 | # push everything through the stream. 98 | if stream.flush() < 0: 99 | echo $sdl2.getError() 100 | quit "failed to flush the stream" 101 | 102 | echo "number of bytes at the stream's output: ", stream.available() 103 | 104 | # calculate the number of bytes in a single output sample. 105 | let nBytesPerSample = hardwareSpec.channels * (SDL_AUDIO_BITSIZE(hardwareSpec.format.uint32) div 8).uint8 106 | 107 | # make a buffer that's just one of those. 108 | 109 | # use a shared allocation! another thread (the audio output thread) 110 | # is going to be playing around with this memory! 111 | var obuf = allocShared(nBytesPerSample) 112 | defer: deallocShared(obuf) 113 | echo "bytes per sample ", nBytesPerSample 114 | 115 | # add the stream's output to the audio device's queue, one sample at a time. 116 | var nread = stream.get(obuf, nBytesPerSample.cint) 117 | while nread > 0: 118 | if deviceId.queueAudio(obuf, nread.uint32) < 0: 119 | echo $sdl2.getError() 120 | quit "failed to queue audio!" 121 | nread = stream.get(obuf, nBytesPerSample.cint) 122 | 123 | # sit in a while loop until the audio device's queue is empty 124 | while deviceId.getQueuedAudioSize() > 0'u32: 125 | discard 126 | 127 | main() 128 | -------------------------------------------------------------------------------- /examples/sdl_mixer_example.nim: -------------------------------------------------------------------------------- 1 | import sdl2, sdl2 / mixer 2 | 3 | # sdl init 4 | sdl2.init(INIT_EVERYTHING) 5 | 6 | #var sound : ChunkPtr 7 | var sound2 : MusicPtr 8 | 9 | var channel : cint 10 | var audio_rate : cint 11 | var audio_format : uint16 12 | var audio_buffers : cint = 4096 13 | var audio_channels : cint = 2 14 | 15 | if mixer.openAudio(audio_rate, audio_format, audio_channels, audio_buffers) != 0: 16 | quit("There was a problem") 17 | 18 | #sound = mixer.loadWAV("SDL_PlaySound/sound.wav") 19 | sound2 = mixer.loadMUS("SDL_PlaySound/sound.ogg") 20 | if isNil(sound2): 21 | quit("Unable to load sound file") 22 | 23 | #channel = mixer.playChannel(-1, sound, 0); #wav 24 | channel = sound2.play(0); #ogg/flac 25 | if channel == -1: 26 | quit("Unable to play sound") 27 | 28 | var 29 | window: WindowPtr 30 | render: RendererPtr 31 | 32 | window = createWindow("SDL Skeleton", 100, 100, 640,480, SDL_WINDOW_SHOWN) 33 | render = createRenderer(window, -1, Renderer_Accelerated or Renderer_PresentVsync or Renderer_TargetTexture) 34 | 35 | #let the sound finish 36 | while mixer.playing(channel) != 0: 37 | discard 38 | 39 | # mixer.freeChunk(sound) #clear wav 40 | mixer.freeMusic(sound2) #clear ogg 41 | mixer.closeAudio() 42 | sdl2.quit() 43 | 44 | # keep window open enough to hear sound, testing purposes 45 | sdl2.delay(1000) 46 | 47 | destroy render 48 | destroy window 49 | -------------------------------------------------------------------------------- /examples/sdl_opengl_example.nim: -------------------------------------------------------------------------------- 1 | # OpenGL example using SDL2 2 | 3 | import sdl2 4 | import opengl 5 | import opengl/glu 6 | 7 | discard sdl2.init(INIT_EVERYTHING) 8 | 9 | var screenWidth: cint = 640 10 | var screenHeight: cint = 480 11 | 12 | var window = createWindow("SDL/OpenGL Skeleton", 100, 100, screenWidth, screenHeight, SDL_WINDOW_OPENGL or SDL_WINDOW_RESIZABLE) 13 | var context = window.glCreateContext() 14 | 15 | # Initialize OpenGL 16 | loadExtensions() 17 | glClearColor(0.0, 0.0, 0.0, 1.0) # Set background color to black and opaque 18 | glClearDepth(1.0) # Set background depth to farthest 19 | glEnable(GL_DEPTH_TEST) # Enable depth testing for z-culling 20 | glDepthFunc(GL_LEQUAL) # Set the type of depth-test 21 | glShadeModel(GL_SMOOTH) # Enable smooth shading 22 | glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) # Nice perspective corrections 23 | 24 | proc reshape(newWidth: cint, newHeight: cint) = 25 | glViewport(0, 0, newWidth, newHeight) # Set the viewport to cover the new window 26 | glMatrixMode(GL_PROJECTION) # To operate on the projection matrix 27 | glLoadIdentity() # Reset 28 | gluPerspective(45.0, newWidth / newHeight, 0.1, 100.0) # Enable perspective projection with fovy, aspect, zNear and zFar 29 | 30 | proc render() = 31 | glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT) # Clear color and depth buffers 32 | glMatrixMode(GL_MODELVIEW) # To operate on model-view matrix 33 | glLoadIdentity() # Reset the model-view matrix 34 | glTranslatef(1.5, 0.0, -7.0) # Move right and into the screen 35 | 36 | # Render a cube consisting of 6 quads 37 | # Each quad consists of 2 triangles 38 | # Each triangle consists of 3 vertices 39 | 40 | glBegin(GL_TRIANGLES) # Begin drawing of triangles 41 | 42 | # Top face (y = 1.0f) 43 | glColor3f(0.0, 1.0, 0.0) # Green 44 | glVertex3f( 1.0, 1.0, -1.0) 45 | glVertex3f(-1.0, 1.0, -1.0) 46 | glVertex3f(-1.0, 1.0, 1.0) 47 | glVertex3f( 1.0, 1.0, 1.0) 48 | glVertex3f( 1.0, 1.0, -1.0) 49 | glVertex3f(-1.0, 1.0, 1.0) 50 | 51 | # Bottom face (y = -1.0f) 52 | glColor3f(1.0, 0.5, 0.0) # Orange 53 | glVertex3f( 1.0, -1.0, 1.0) 54 | glVertex3f(-1.0, -1.0, 1.0) 55 | glVertex3f(-1.0, -1.0, -1.0) 56 | glVertex3f( 1.0, -1.0, -1.0) 57 | glVertex3f( 1.0, -1.0, 1.0) 58 | glVertex3f(-1.0, -1.0, -1.0) 59 | 60 | # Front face (z = 1.0f) 61 | glColor3f(1.0, 0.0, 0.0) # Red 62 | glVertex3f( 1.0, 1.0, 1.0) 63 | glVertex3f(-1.0, 1.0, 1.0) 64 | glVertex3f(-1.0, -1.0, 1.0) 65 | glVertex3f( 1.0, -1.0, 1.0) 66 | glVertex3f( 1.0, 1.0, 1.0) 67 | glVertex3f(-1.0, -1.0, 1.0) 68 | 69 | # Back face (z = -1.0f) 70 | glColor3f(1.0, 1.0, 0.0) # Yellow 71 | glVertex3f( 1.0, -1.0, -1.0) 72 | glVertex3f(-1.0, -1.0, -1.0) 73 | glVertex3f(-1.0, 1.0, -1.0) 74 | glVertex3f( 1.0, 1.0, -1.0) 75 | glVertex3f( 1.0, -1.0, -1.0) 76 | glVertex3f(-1.0, 1.0, -1.0) 77 | 78 | # Left face (x = -1.0f) 79 | glColor3f(0.0, 0.0, 1.0) # Blue 80 | glVertex3f(-1.0, 1.0, 1.0) 81 | glVertex3f(-1.0, 1.0, -1.0) 82 | glVertex3f(-1.0, -1.0, -1.0) 83 | glVertex3f(-1.0, -1.0, 1.0) 84 | glVertex3f(-1.0, 1.0, 1.0) 85 | glVertex3f(-1.0, -1.0, -1.0) 86 | 87 | # Right face (x = 1.0f) 88 | glColor3f(1.0, 0.0, 1.0) # Magenta 89 | glVertex3f(1.0, 1.0, -1.0) 90 | glVertex3f(1.0, 1.0, 1.0) 91 | glVertex3f(1.0, -1.0, 1.0) 92 | glVertex3f(1.0, -1.0, -1.0) 93 | glVertex3f(1.0, 1.0, -1.0) 94 | glVertex3f(1.0, -1.0, 1.0) 95 | 96 | glEnd() # End of drawing 97 | 98 | window.glSwapWindow() # Swap the front and back frame buffers (double buffering) 99 | 100 | # Frame rate limiter 101 | 102 | let targetFramePeriod: uint32 = 20 # 20 milliseconds corresponds to 50 fps 103 | var frameTime: uint32 = 0 104 | 105 | proc limitFrameRate() = 106 | let now = getTicks() 107 | if frameTime > now: 108 | delay(frameTime - now) # Delay to maintain steady frame rate 109 | frameTime += targetFramePeriod 110 | 111 | # Main loop 112 | 113 | var 114 | evt = sdl2.defaultEvent 115 | runGame = true 116 | 117 | reshape(screenWidth, screenHeight) # Set up initial viewport and projection 118 | 119 | while runGame: 120 | while pollEvent(evt): 121 | if evt.kind == QuitEvent: 122 | runGame = false 123 | break 124 | if evt.kind == WindowEvent: 125 | var windowEvent = cast[WindowEventPtr](addr(evt)) 126 | if windowEvent.event == WindowEvent_Resized: 127 | let newWidth = windowEvent.data1 128 | let newHeight = windowEvent.data2 129 | reshape(newWidth, newHeight) 130 | 131 | render() 132 | 133 | limitFrameRate() 134 | 135 | destroy window 136 | -------------------------------------------------------------------------------- /examples/sdl_skeleton.nim: -------------------------------------------------------------------------------- 1 | ## Bare-bones SDL2 example 2 | import sdl2 3 | 4 | discard sdl2.init(INIT_EVERYTHING) 5 | 6 | var 7 | window: WindowPtr 8 | render: RendererPtr 9 | 10 | window = createWindow("SDL Skeleton", 100, 100, 640,480, SDL_WINDOW_SHOWN) 11 | render = createRenderer(window, -1, Renderer_Accelerated or Renderer_PresentVsync or Renderer_TargetTexture) 12 | 13 | var 14 | evt = sdl2.defaultEvent 15 | runGame = true 16 | 17 | while runGame: 18 | while pollEvent(evt): 19 | if evt.kind == QuitEvent: 20 | runGame = false 21 | break 22 | 23 | render.setDrawColor 0,0,0,255 24 | render.clear 25 | render.present 26 | 27 | destroy render 28 | destroy window 29 | -------------------------------------------------------------------------------- /sdl2.nimble: -------------------------------------------------------------------------------- 1 | # Package 2 | version = "2.0.5" 3 | author = "fowl" 4 | description = "Wrapper for SDL 2.x" 5 | license = "MIT" 6 | 7 | srcDir = "src" 8 | 9 | # Deps 10 | requires "nim >= 0.12.0" 11 | 12 | -------------------------------------------------------------------------------- /src/sdl2/audio.nim: -------------------------------------------------------------------------------- 1 | # Simple DirectMedia Layer 2 | # Copyright (C) 1997-2013 Sam Lantinga 3 | # 4 | # This software is provided 'as-is', without any express or implied 5 | # warranty. In no event will the authors be held liable for any damages 6 | # arising from the use of this software. 7 | # 8 | # Permission is granted to anyone to use this software for any purpose, 9 | # including commercial applications, and to alter it and redistribute it 10 | # freely, subject to the following restrictions: 11 | # 12 | # 1. The origin of this software must not be misrepresented; you must not 13 | # claim that you wrote the original software. If you use this software 14 | # in a product, an acknowledgment in the product documentation would be 15 | # appreciated but is not required. 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 3. This notice may not be removed or altered from any source distribution. 19 | 20 | 21 | 22 | ## Access to the raw audio mixing buffer for the SDL library. 23 | 24 | import sdl2 25 | 26 | 27 | type 28 | AudioFormat* = uint16 29 | ## Audio format flags. 30 | ## 31 | ## These are what the 16 bits in `AudioFormat` currently mean... 32 | ## (Unspecified bits are always zero). 33 | ## 34 | ## ++-----------------------sample is signed if set 35 | ## || 36 | ## || ++-----------sample is bigendian if set 37 | ## || || 38 | ## || || ++---sample is float if set 39 | ## || || || 40 | ## || || || +---sample bit size---+ 41 | ## || || || | | 42 | ## 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 43 | ## 44 | ## There are templates in SDL 2.0 and later to query these bits. 45 | 46 | const 47 | SDL_AUDIO_MASK_BITSIZE* = uint32(0x000000FF) 48 | SDL_AUDIO_MASK_DATATYPE* = uint32(1 shl 8) 49 | SDL_AUDIO_MASK_ENDIAN* = uint32(1 shl 12) 50 | SDL_AUDIO_MASK_SIGNED* = uint32(1 shl 15) 51 | 52 | template SDL_AUDIO_BITSIZE*(x: uint32): uint32 = 53 | (x and SDL_AUDIO_MASK_BITSIZE) 54 | 55 | template SDL_AUDIO_ISFLOAT*(x: uint32): bool = 56 | (x and SDL_AUDIO_MASK_DATATYPE) != 0 57 | 58 | template SDL_AUDIO_ISBIGENDIAN*(x: uint32): bool = 59 | (x and SDL_AUDIO_MASK_ENDIAN) != 0 60 | 61 | template SDL_AUDIO_ISSIGNED*(x: uint32): bool = 62 | (x and SDL_AUDIO_MASK_SIGNED) != 0 63 | 64 | template SDL_AUDIO_ISINT*(x: uint32): bool = 65 | not SDL_AUDIO_ISFLOAT(x) 66 | 67 | template SDL_AUDIO_ISLITTLEENDIAN*(x: uint32): bool = 68 | not SDL_AUDIO_ISBIGENDIAN(x) 69 | 70 | template SDL_AUDIO_ISUNSIGNED*(x: uint32): bool = 71 | not SDL_AUDIO_ISSIGNED(x) 72 | 73 | 74 | # Audio format flags 75 | # 76 | # Defaults to LSB byte order. 77 | const 78 | AUDIO_U8* = 0x00000008 ## Unsigned 8-bit samples 79 | AUDIO_S8* = 0x00008008 ## Signed 8-bit samples 80 | AUDIO_U16LSB* = 0x00000010 ## Unsigned 16-bit samples 81 | AUDIO_S16LSB* = 0x00008010 ## Signed 16-bit samples 82 | AUDIO_U16MSB* = 0x00001010 ## As above, but big-endian byte order 83 | AUDIO_S16MSB* = 0x00009010 ## As above, but big-endian byte order 84 | AUDIO_U16* = AUDIO_U16LSB 85 | AUDIO_S16* = AUDIO_S16LSB 86 | 87 | # int32 support 88 | const 89 | AUDIO_S32LSB* = 0x00008020 ## 32-bit integer samples 90 | AUDIO_S32MSB* = 0x00009020 ## As above, but big-endian byte order 91 | AUDIO_S32* = AUDIO_S32LSB 92 | 93 | # float32 support 94 | const 95 | AUDIO_F32LSB* = 0x00008120 ## 32-bit floating point samples 96 | AUDIO_F32MSB* = 0x00009120 ## As above, but big-endian byte order 97 | AUDIO_F32* = AUDIO_F32LSB 98 | 99 | # Native audio byte ordering 100 | when false: 101 | # TODO system.cpuEndian 102 | when SDL_BYTEORDER == SDL_LIL_ENDIAN: 103 | const 104 | AUDIO_U16SYS* = AUDIO_U16LSB 105 | AUDIO_S16SYS* = AUDIO_S16LSB 106 | AUDIO_S32SYS* = AUDIO_S32LSB 107 | AUDIO_F32SYS* = AUDIO_F32LSB 108 | else: 109 | const 110 | AUDIO_U16SYS* = AUDIO_U16MSB 111 | AUDIO_S16SYS* = AUDIO_S16MSB 112 | AUDIO_S32SYS* = AUDIO_S32MSB 113 | AUDIO_F32SYS* = AUDIO_F32MSB 114 | 115 | # Allow change flags 116 | # 117 | # Which audio format changes are allowed when opening a device. 118 | const 119 | SDL_AUDIO_ALLOW_FREQUENCY_CHANGE* = 0x00000001 120 | SDL_AUDIO_ALLOW_FORMAT_CHANGE* = 0x00000002 121 | SDL_AUDIO_ALLOW_CHANNELS_CHANGE* = 0x00000004 122 | SDL_AUDIO_ALLOW_ANY_CHANGE* = (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE or 123 | SDL_AUDIO_ALLOW_FORMAT_CHANGE or SDL_AUDIO_ALLOW_CHANNELS_CHANGE) 124 | 125 | # Audio flags 126 | type 127 | AudioCallback* = proc (userdata: pointer; stream: ptr uint8; len: cint) {.cdecl.} 128 | ## This procedure is called when the audio device needs more data. 129 | ## 130 | ## `userdata` An application-specific parameter 131 | ## saved in `AudioSpec` object. 132 | ## 133 | ## `stream` A pointer to the audio data buffer. 134 | ## 135 | ## `len` The length of that buffer in bytes. 136 | ## 137 | ## Once the callback returns, the buffer will no longer be valid. 138 | ## Stereo samples are stored in a LRLRLR ordering. 139 | ## 140 | ## You can choose to avoid callbacks and use `queueAudio()` instead, 141 | ## if you like. Just open your audio device with a `nil` callback. 142 | 143 | type 144 | AudioSpec* = object 145 | ## The calculated values in this object are calculated by `OpenAudio()`. 146 | ## 147 | ## For multi-channel audio, the default SDL channel mapping is: 148 | ## * 2: FL FR (stereo) 149 | ## * 3: FL FR LFE (2.1 surround) 150 | ## * 4: FL FR BL BR (quad) 151 | ## * 5: FL FR FC BL BR (quad + center) 152 | ## * 6: FL FR FC LFE SL SR (5.1 surround - last two can also be BL BR) 153 | ## * 7: FL FR FC LFE BC SL SR (6.1 surround) 154 | ## * 8: FL FR FC LFE BL BR SL SR (7.1 surround) 155 | freq*: cint ## DSP frequency -- samples per second 156 | format*: AudioFormat ## Audio data format 157 | channels*: uint8 ## Number of channels: 1 mono, 2 stereo 158 | silence*: uint8 ## Audio buffer silence value (calculated) 159 | samples*: uint16 ## Audio buffer size in samples (power of 2) 160 | padding*: uint16 ## Necessary for some compile environments 161 | size*: uint32 ## Audio buffer size in bytes (calculated) 162 | callback*: AudioCallback 163 | ## Callback that feeds the audio device (`nil` to use `queueAudio()`). 164 | userdata*: pointer 165 | ## Userdata passed to callback (ignored for `nil` callbacks). 166 | 167 | AudioCVT* {.packed.} = object 168 | ## A structure to hold a set of audio conversion filters and buffers. 169 | ## 170 | ## Note that various parts of the conversion pipeline can take advantage 171 | ## of SIMD operations (like SSE2, for example). `AudioCVT` doesn't 172 | ## require you to pass it aligned data, but can possibly run much faster 173 | ## if you set both its `buf` field to a pointer that is aligned to 16 174 | ## bytes, and its `len` field to something that's a multiple of 16, 175 | ## if possible. 176 | ## 177 | ## This structure is 84 bytes on 32-bit architectures, make sure GCC 178 | ## doesn't pad it out to 88 bytes to guarantee ABI compatibility between 179 | ## compilers. The next time we rev the ABI, make sure to size the ints 180 | ## and add padding. 181 | needed*: cint ## Set to 1 if conversion possible 182 | src_format*: AudioFormat ## Source audio format 183 | dst_format*: AudioFormat ## Target audio format 184 | rate_incr*: cdouble ## Rate conversion increment 185 | buf*: ptr uint8 ## Buffer to hold entire audio data 186 | len*: cint ## Length of original audio buffer 187 | len_cvt*: cint ## Length of converted audio buffer 188 | len_mult*: cint ## buffer must be len*len_mult big 189 | len_ratio*: cdouble ## Given len, final size is len*len_ratio 190 | filters*: array[10, AudioFilter] ## Filter list 191 | filter_index*: cint ## Current audio conversion function 192 | 193 | AudioFilter* = proc (cvt: ptr AudioCVT; format: AudioFormat){.cdecl.} 194 | 195 | type 196 | AudioStream = object 197 | ## a new audio conversion interface. 198 | ## 199 | ## The benefits vs `AudioCVT`: 200 | ## * it can handle resampling data in chunks without generating 201 | ## artifacts, when it doesn't have the complete buffer available. 202 | ## * it can handle incoming data in any variable size. 203 | ## * You push data as you have it, and pull it when you need it. 204 | ## 205 | ## This is opaque to the outside world. 206 | cvt_before_resampling*: AudioCVT 207 | cvt_after_resampling*: AudioCVT 208 | queue*: pointer 209 | first_run*: Bool32 210 | staging_buffer*: ptr uint8 211 | staging_buffer_size*: cint 212 | staging_buffer_filled*: cint 213 | work_buffer_base*: ptr uint8 # maybe unaligned pointer from SDL_realloc(). 214 | work_buffer_len*: cint 215 | src_sample_frame_size*: cint 216 | src_format*: AudioFormat 217 | src_channels*: uint8 218 | src_rate*: cint 219 | dst_sample_frame_size*: cint 220 | dst_format*: AudioFormat 221 | dst_channels*: uint8 222 | dst_rate*: cint 223 | rate_incr*: cdouble 224 | pre_resample_channels*: uint8 225 | packetlen*: cint 226 | resampler_padding_samples*: cint 227 | resampler_padding*: ptr cfloat 228 | resampler_state*: pointer 229 | resampler_func*: proc(stream: AudioStreamPtr, 230 | inbuf: pointer, inbuflen: cint, 231 | outbuf: pointer, outbuflen: cint): cint 232 | reset_resampler_func*: proc(stream: AudioStreamPtr) 233 | cleanup_resampler_func*: proc(stream: AudioStreamPtr) 234 | 235 | AudioStreamPtr* = ptr AudioStream 236 | ## (Available since SDL 2.0.7) 237 | ## A pointer to an `AudioStream`. Audio streams were added to SDL2 238 | ## in version 2.0.7, to provide an easier-to-use alternative to 239 | ## `AudioCVT`. 240 | ## 241 | ## .. _SDL_AudioStream: https://wiki.libsdl.org/Tutorials/AudioStream 242 | ## .. _SDL_AudioCVT: https://wiki.libsdl.org/SDL_AudioCVT 243 | ## 244 | ## **See also:** 245 | ## * `newAudioStream proc<#newAudioStream,AudioFormat,uint8,cint,AudioFormat,uint8,cint>`_ 246 | ## * `newAudioStream proc<#newAudioStream,AudioSpec,AudioSpec>`_ 247 | ## * `put proc<#put,AudioStreamPtr,pointer,cint>`_ 248 | ## * `get proc<#get,AudioStreamPtr,pointer,cint>`_ 249 | ## * `available proc<#available,AudioStreamPtr>`_ 250 | ## * `flush proc<#flush,AudioStreamPtr>`_ 251 | ## * `clear proc<#clear,AudioStreamPtr>`_ 252 | ## * `destroy proc<#destroy,AudioStreamPtr>`_ 253 | 254 | when false: 255 | 256 | when defined(GNUC):#__GNUC__): 257 | # This structure is 84 bytes on 32-bit architectures, make sure GCC doesn't 258 | # pad it out to 88 bytes to guarantee ABI compatibility between compilers. 259 | # vvv 260 | # The next time we rev the ABI, make sure to size the ints and add padding. 261 | # 262 | const 263 | AudioCVT_PACKED* = x#__attribute__((packed)) 264 | else: 265 | const 266 | AudioCVT_PACKED* = true 267 | 268 | 269 | type 270 | AudioDeviceID* = uint32 271 | ## SDL Audio Device IDs. 272 | ## 273 | ## A successful call to `openAudio()` is always device id `1`, and legacy 274 | ## SDL audio APIs assume you want this device ID. 275 | ## `openAudioDevice()` calls always returns devices >= `2` on success. 276 | ## The legacy calls are good both for backwards compatibility and when you 277 | ## don't care about multiple, specific, or capture devices. 278 | 279 | type 280 | AudioStatus* {.size: sizeof(cint).} = enum 281 | SDL_AUDIO_STOPPED = 0, SDL_AUDIO_PLAYING, SDL_AUDIO_PAUSED 282 | const 283 | SDL_MIX_MAXVOLUME* = 128 284 | 285 | when defined(SDL_Static): 286 | static: echo "SDL_Static option is deprecated and will soon be removed. Instead please use --dynlibOverride:SDL2." 287 | else: 288 | {.push callConv: cdecl, dynlib: LibName.} 289 | 290 | proc getNumAudioDrivers*(): cint {.importc: "SDL_GetNumAudioDrivers".} 291 | ## Driver discovery procedures. 292 | ## 293 | ## These procedures return the list of built in audio drivers, in the 294 | ## order that they are normally initialized by default. 295 | 296 | proc getAudioDriver*(index: cint): cstring {.importc: "SDL_GetAudioDriver".} 297 | ## Driver discovery procedures. 298 | ## 299 | ## These procedures return the list of built in audio drivers, in the 300 | ## order that they are normally initialized by default. 301 | 302 | proc audioInit*(driver_name: cstring): cint {.importc: "SDL_AudioInit".} 303 | ## Initialization. 304 | ## 305 | ## `Internal:` These procedures are used internally, and should not be used 306 | ## unless you have a specific need to specify the audio driver you want to 307 | ## use. You should normally use `init()` or `initSubSystem()`. 308 | 309 | proc audioQuit*() {.importc: "SDL_AudioQuit".} 310 | ## Cleanup. 311 | ## 312 | ## `Internal`: These procedures are used internally, and should not be used 313 | ## unless you have a specific need to specify the audio driver you want to 314 | ## use. You should normally use `init()` or `initSubSystem()`. 315 | 316 | proc getCurrentAudioDriver*(): cstring {.importc: "SDL_GetCurrentAudioDriver".} 317 | ## This procedure returns the name of the current audio driver, or `nil` 318 | ## if no driver has been initialized. 319 | 320 | proc openAudio*(desired: ptr AudioSpec; obtained: ptr AudioSpec): cint {. 321 | importc: "SDL_OpenAudio".} 322 | ## This procedure opens the audio device with the desired parameters, and 323 | ## returns `0` if successful, placing the actual hardware parameters in the 324 | ## object pointed to by `obtained`. If `obtained` is `nil`, the audio 325 | ## data passed to the callback procedure will be guaranteed to be in the 326 | ## requested format, and will be automatically converted to the hardware 327 | ## audio format if necessary. This procedure returns `-1` if it failed 328 | ## to open the audio device, or couldn't set up the audio thread. 329 | ## 330 | ## When filling in the `desired` audio spec object, 331 | ## * `desired.freq` should be the desired audio frequency 332 | ## in samples-per- second. 333 | ## * `desired.format` should be the desired audio format. 334 | ## * `desired.samples` is the desired size of the audio buffer, 335 | ## in samples. This number should be a power of two, and may be adjusted 336 | ## by the audio driver to a value more suitable for the hardware. 337 | ## Good values seem to range between `512` and `8096` inclusive, depending 338 | ## on the application and CPU speed. Smaller values yield faster 339 | ## response time, but can lead to underflow if the application is doing 340 | ## heavy processing and cannot fill the audio buffer in time. A stereo 341 | ## sample consists of both right and left channels in LR ordering. 342 | ## 343 | ## Note that the number of samples is directly related to time by the 344 | ## following formula: 345 | ## 346 | ## `ms = (samples*1000)/freq` 347 | ## 348 | ## * `desired.size` is the size in bytes of the audio buffer, and is 349 | ## calculated by `openAudio()`. 350 | ## * `desired.silence` is the value used to set the buffer to silence, 351 | ## and is calculated by `openAudio()`. 352 | ## * `desired.callback` should be set to a procedure that will be called 353 | ## when the audio device is ready for more data. It is passed a pointer 354 | ## to the audio buffer, and the length in bytes of the audio buffer. 355 | ## This procedure usually runs in a separate thread, and so you should 356 | ## protect data structures that it accesses by calling `lockAudio()` 357 | ## and `unlockAudio()` in your code. Alternately, you may pass a `nil` 358 | ## pointer here, and call `queueAudio()` with some frequency, to queue 359 | ## more audio samples to be played (or for capture devices, call 360 | ## `sdl.dequeueAudio()` with some frequency, to obtain audio samples). 361 | ## * `desired.userdata` is passed as the first parameter to your callback 362 | ## procedure. If you passed a `nil` callback, this value is ignored. 363 | ## 364 | ## The audio device starts out playing silence when it's opened, and should 365 | ## be enabled for playing by calling `pauseAudio(0)` when you are ready 366 | ## for your audio callback procedure to be called. Since the audio driver 367 | ## may modify the requested size of the audio buffer, you should allocate 368 | ## any local mixing buffers after you open the audio device. 369 | 370 | proc getNumAudioDevices*(iscapture: cint): cint {. 371 | importc: "SDL_GetNumAudioDevices".} 372 | ## Get the number of available devices exposed by the current driver. 373 | ## 374 | ## Only valid after a successfully initializing the audio subsystem. 375 | ## Returns `-1` if an explicit list of devices can't be determined; this is 376 | ## not an error. For example, if SDL is set up to talk to a remote audio 377 | ## server, it can't list every one available on the Internet, but it will 378 | ## still allow a specific host to be specified to `openAudioDevice()`. 379 | ## 380 | ## In many common cases, when this procedure returns a value <= `0`, 381 | ## it can still successfully open the default device (`nil` for first 382 | ## argument of `openAudioDevice()`). 383 | 384 | proc getAudioDeviceName*(index: cint; iscapture: cint): cstring {. 385 | importc: "SDL_GetAudioDeviceName".} 386 | ## Get the human-readable name of a specific audio device. 387 | ## 388 | ## Must be a value between `0` and `(number of audio devices-1)`. 389 | ## Only valid after a successfully initializing the audio subsystem. 390 | ## The values returned by this procedure reflect the latest call to 391 | ## `getNumAudioDevices()`; recall that procedure to redetect available 392 | ## hardware. 393 | ## 394 | ## The string returned by this procedure is UTF-8 encoded, read-only, and 395 | ## managed internally. You are not to free it. If you need to keep the 396 | ## string for any length of time, you should make your own copy of it, as it 397 | ## will be invalid next time any of several other SDL prodedures is called. 398 | 399 | proc openAudioDevice*(device: cstring; iscapture: cint; 400 | desired: ptr AudioSpec; 401 | obtained: ptr AudioSpec; 402 | allowed_changes: cint): AudioDeviceID {. 403 | importc: "SDL_OpenAudioDevice".} 404 | ## Open a specific audio device. 405 | ## 406 | ## Passing in a device name of `nil` requests the most reasonable default 407 | ## (and is equivalent to calling `openAudio()`). 408 | ## 409 | ## The device name is a UTF-8 string reported by `getAudioDeviceName()`, 410 | ## but some drivers allow arbitrary and driver-specific strings, such as a 411 | ## hostname/IP address for a remote audio server, or a filename in the 412 | ## diskaudio driver. 413 | ## 414 | ## `Return` `0` on error, a valid device ID that is >= `2` on success. 415 | ## 416 | ## `openAudio()`, unlike this procedure, always acts on device ID `1`. 417 | 418 | 419 | proc getAudioStatus*(): AudioStatus {.importc: "SDL_GetAudioStatus".} 420 | ## Get the current audio state. 421 | 422 | proc getAudioDeviceStatus*(dev: AudioDeviceID): AudioStatus {. 423 | importc: "SDL_GetAudioDeviceStatus".} 424 | ## Get the current audio state. 425 | 426 | proc getQueuedAudioSize*(dev: AudioDeviceID): uint32 {. 427 | importc: "SDL_GetQueuedAudioSize".} 428 | ## Get the number of bytes of still-queued audio. 429 | ## 430 | ## `For playback device:` 431 | ## This is the number of bytes that have been queued for playback with 432 | ## `sdl.queueAudio()`, but have not yet been sent to the hardware. This 433 | ## number may shrink at any time, so this only informs of pending data. 434 | ## 435 | ## Once we've sent it to the hardware, this procedure can not decide the 436 | ## exact byte boundary of what has been played. It's possible that we just 437 | ## gave the hardware several kilobytes right before you called this 438 | ## procedure, but it hasn't played any of it yet, or maybe half of it, etc. 439 | ## 440 | ## `For capture device:` 441 | ## This is the number of bytes that have been captured by the device and 442 | ## are waiting for you to dequeue. This number may grow at any time, so 443 | ## this only informs of the lower-bound of available data. 444 | ## 445 | ## You may not queue audio on a device that is using an application-supplied 446 | ## callback; calling this procedure on such a device always returns `0`. 447 | ## You have to queue audio with `sdl.queueAudio()` / 448 | ## `sdl.dequeueAudio()`, or use the audio callback, but not both. 449 | ## 450 | ## You should not call `lockAudio()` on the device before querying; SDL 451 | ## handles locking internally for this procedure. 452 | ## 453 | ## `dev` The device ID of which we will query queued audio size. 454 | ## 455 | ## `Return` number of bytes (not samples!) of queued audio. 456 | ## 457 | ## **See also:** 458 | ## * `queueAudio proc<#queueAudio,AudioDeviceID,pointer,uint32>`_ 459 | 460 | proc queueAudio*(dev: AudioDeviceID, data: pointer, len: uint32): cint {. 461 | importc: "SDL_QueueAudio".} 462 | ## Queue more audio on non-callback devices. 463 | ## 464 | ## (If you are looking to retrieve queued audio from a non-callback capture 465 | ## device, you want `sdl.dequeueAudio()` instead. This will return `-1` 466 | ## to signify an error if you use it with capture devices.) 467 | ## 468 | ## SDL offers two ways to feed audio to the device: you can either supply a 469 | ## callback that SDL triggers with some frequency to obtain more audio 470 | ## (pull method), or you can supply no callback, and then SDL will expect 471 | ## you to supply data at regular intervals (push method) with this procedure. 472 | ## 473 | ## There are no limits on the amount of data you can queue, short of 474 | ## exhaustion of address space. Queued data will drain to the device as 475 | ## necessary without further intervention from you. If the device needs 476 | ## audio but there is not enough queued, it will play silence to make up 477 | ## the difference. This means you will have skips in your audio playback 478 | ## if you aren't routinely queueing sufficient data. 479 | ## 480 | ## This procedure copies the supplied data, so you are safe to free it when 481 | ## the procedure returns. This procedure is thread-safe, but queueing to the 482 | ## same device from two threads at once does not promise which buffer will 483 | ## be queued first. 484 | ## 485 | ## You may not queue audio on a device that is using an application-supplied 486 | ## callback; doing so returns an error. You have to use the audio callback 487 | ## or queue audio with this procedure, but not both. 488 | ## 489 | ## You should not call `lockAudio()` on the device before queueing; SDL 490 | ## handles locking internally for this procedure. 491 | ## 492 | ## `dev` The device ID to which we will queue audio. 493 | ## 494 | ## `data` The data to queue to the device for later playback. 495 | ## 496 | ## `len` The number of bytes (not samples!) to which (data) points. 497 | ## 498 | ## `Return` `0` on success, `-1` on error. 499 | ## 500 | ## **See also:** 501 | ## * `getQueuedAudioSize proc<#getQueuedAudioSize,AudioDeviceID>`_ 502 | 503 | proc dequeueAudio*(dev: AudioDeviceID, data: pointer, len: uint32): cint {. 504 | importc: "SDL_DequeueAudio".} 505 | ## Dequeue more audio on non-callback devices. 506 | ## 507 | ## (If you are looking to queue audio for output on a non-callback playback 508 | ## device, you want `sdl.queueAudio()` instead. This will always return 509 | ## `0` if you use it with playback devices.) 510 | ## 511 | ## SDL offers two ways to retrieve audio from a capture device: you can 512 | ## either supply a callback that SDL triggers with some frequency as the 513 | ## device records more audio data, (push method), or you can supply no 514 | ## callback, and then SDL will expect you to retrieve data at regular 515 | ## intervals (pull method) with this procedure. 516 | ## 517 | ## There are no limits on the amount of data you can queue, short of 518 | ## exhaustion of address space. Data from the device will keep queuing as 519 | ## necessary without further intervention from you. This means you will 520 | ## eventually run out of memory if you aren't routinely dequeueing data. 521 | ## 522 | ## Capture devices will not queue data when paused; if you are expecting 523 | ## to not need captured audio for some length of time, use 524 | ## `sdl.pauseAudioDevice()` to stop the capture device from queueing more 525 | ## data. This can be useful during, say, level loading times. When 526 | ## unpaused, capture devices will start queueing data from that point, 527 | ## having flushed any capturable data available while paused. 528 | ## 529 | ## This procedure is thread-safe, but dequeueing from the same device from 530 | ## two threads at once does not promise which thread will dequeued data 531 | ## first. 532 | ## 533 | ## You may not dequeue audio from a device that is using an 534 | ## application-supplied callback; doing so returns an error. You have to use 535 | ## the audio callback, or dequeue audio with this procedure, but not both. 536 | ## 537 | ## You should not call `sdl.lockAudio()` on the device before queueing; 538 | ## SDL handles locking internally for this procedure. 539 | ## 540 | ## `dev` The device ID from which we will dequeue audio. 541 | ## 542 | ## `data` A pointer into where audio data should be copied. 543 | ## 544 | ## `len` The number of bytes (not samples!) to which (data) points. 545 | ## 546 | ## `Return` number of bytes dequeued, which could be less than requested. 547 | ## 548 | ## **See also:** 549 | ## * `getQueuedAudioSize proc<#getQueuedAudioSize,AudioDeviceID>`_ 550 | 551 | proc pauseAudio*(pause_on: cint) {.importc: "SDL_PauseAudio".} 552 | ## Pause audio procedures. 553 | ## 554 | ## These procedures pause and unpause the audio callback processing. 555 | ## They should be called with a parameter of `0` after opening the audio 556 | ## device to start playing sound. This is so you can safely initialize 557 | ## data for your callback procedure after opening the audio device. 558 | ## Silence will be written to the audio device during the pause. 559 | 560 | proc pauseAudioDevice*(dev: AudioDeviceID; pause_on: cint) {. 561 | importc: "SDL_PauseAudioDevice".} 562 | ## Pause audio procedures. 563 | ## 564 | ## These procedures pause and unpause the audio callback processing. 565 | ## They should be called with a parameter of `0` after opening the audio 566 | ## device to start playing sound. This is so you can safely initialize 567 | ## data for your callback procedure after opening the audio device. 568 | ## Silence will be written to the audio device during the pause. 569 | 570 | proc loadWAV_RW*(src: ptr RWops; freesrc: cint; 571 | spec: ptr AudioSpec; audio_buf: ptr ptr uint8; 572 | audio_len: ptr uint32): ptr AudioSpec {. 573 | importc: "SDL_LoadWAV_RW".} 574 | ## Load the audio data of a WAVE file into memory. 575 | ## 576 | ## Loading a WAVE file requires `src`, `spec`, `audio_buf` and 577 | ## `audio_len` to be valid pointers. The entire data portion of the file 578 | ## is then loaded into memory and decoded if necessary. 579 | ## 580 | ## If `freesrc` is non-zero, the data source gets automatically closed and 581 | ## freed before the procedure returns. 582 | ## 583 | ## Supported are RIFF WAVE files with the formats PCM 584 | ## (8, 16, 24, and 32 bits), IEEE Float (32 bits), Microsoft ADPCM and IMA 585 | ## ADPCM (4 bits), and A-law and µ-law (8 bits). Other formats are currently 586 | ## unsupported and cause an error. 587 | ## 588 | ## If this procedure succeeds, the pointer returned by it is equal to 589 | ## `spec` and the pointer to the audio data allocated by the procedure is 590 | ## written to `audio_buf` and its length in bytes to `audio_len`. 591 | ## The `sdl.AudioSpec` members `freq`, `channels`, and `format` are 592 | ## set to the values of the audio data in the buffer. The `samples` member 593 | ## is set to a sane default and all others are set to zero. 594 | ## 595 | ## It's necessary to use `sdl.freeWAV()` to free the audio data returned 596 | ## in `audio_buf` when it is no longer used. 597 | ## 598 | ## Because of the underspecification of the Waveform format, there are many 599 | ## problematic files in the wild that cause issues with strict decoders. To 600 | ## provide compatibility with these files, this decoder is lenient in regards 601 | ## to the truncation of the file, the fact chunk, and the size of the RIFF 602 | ## chunk. The hints `sdl.HINT_WAVE_RIFF_CHUNK_SIZE`, 603 | ## `sdl.HINT_WAVE_TRUNCATION`, and `sdl.HINT_WAVE_FACT_CHUNK` 604 | ## can be used to tune the behavior of the loading process. 605 | ## 606 | ## Any file that is invalid (due to truncation, corruption, or wrong values 607 | ## in the headers), too big, or unsupported causes an error. Additionally, 608 | ## any critical I/O error from the data source will terminate the loading 609 | ## process with an error. The procedure returns `nil` on error and in all 610 | ## cases (with the exception of `src` being `nil`), an appropriate error 611 | ## message will be set. 612 | ## 613 | ## It is required that the data source supports seeking. 614 | ## 615 | ## Example: 616 | ## 617 | ## .. code-block:: nim 618 | ## sdl.loadWAV_RW(sdl.rwFromFile("sample.wav", "rb"), 1, ...) 619 | ## 620 | ## `src` The data source with the WAVE data 621 | ## 622 | ## `freesrc` A integer value that makes the procedure close the data source 623 | ## if non-zero 624 | ## 625 | ## `spec` A pointer filled with the audio format of the audio data 626 | ## 627 | ## `audio_buf` A pointer filled with the audio data allocated by the 628 | ## procedure 629 | ## 630 | ## `audio_len` A pointer filled with the length of the audio data buffer 631 | ## in bytes 632 | ## 633 | ## `Return` `nil` on error, or non-`nil` on success. 634 | 635 | template loadWAV*(file: string, spec: ptr AudioSpec, audio_buf: ptr ptr uint8, audio_len: ptr uint32): ptr AudioSpec = 636 | ## Loads a WAV from a file. 637 | ## Compatibility convenience template. 638 | loadWAV_RW(rwFromFile(file, "rb"), 1, spec, audio_buf, audio_len) 639 | 640 | proc freeWAV*(audio_buf: ptr uint8) {.importc: "SDL_FreeWAV".} 641 | ## This procedure frees data previously allocated with `loadWAV_RW()` 642 | 643 | proc buildAudioCVT*(cvt: ptr AudioCVT; src_format: AudioFormat; 644 | src_channels: uint8; src_rate: cint; 645 | dst_format: AudioFormat; dst_channels: uint8; 646 | dst_rate: cint): cint {. 647 | importc: "SDL_BuildAudioCVT".} 648 | ## This procedure takes a source format and rate and a destination format 649 | ## and rate, and initializes the `cvt` object with information needed 650 | ## by `convertAudio()` to convert a buffer of audio data from one format 651 | ## to the other. An unsupported format causes an error and `-1` will be 652 | ## returned. 653 | ## 654 | ## `Return` `0` if no conversion is needed, 655 | ## `1` if the audio filter is set up, or `-1` on error. 656 | 657 | proc convertAudio*(cvt: ptr AudioCVT): cint {.importc: "SDL_ConvertAudio".} 658 | ## Once you have initialized the `cvt` object using `buildAudioCVT()`, 659 | ## created an audio buffer `cvt.buf`, and filled it with `cvt.len` bytes 660 | ## of audio data in the source format, this procedure will convert it 661 | ## in-place to the desired format. 662 | ## 663 | ## The data conversion may expand the size of the audio data, so the buffer 664 | ## `cvt.buf` should be allocated after the `cvt` object is initialized 665 | ## by `buildAudioCVT()`, and should be `cvt.len*cvt.len_mult` bytes long. 666 | ## 667 | ## `Return` `0` on success or `-1` if `cvt.buf` is `nil`. 668 | 669 | proc mixAudio*(dst: ptr uint8; src: ptr uint8; len: uint32; volume: cint) {. 670 | importc: "SDL_MixAudio".} 671 | ## This takes two audio buffers of the playing audio format and mixes 672 | ## them, performing addition, volume adjustment, and overflow clipping. 673 | ## The volume ranges from `0 - 128`, and should be set to `MIX_MAXVOLUME` 674 | ## for full audio volume. Note this does not change hardware volume. 675 | ## This is provided for convenience -- you can mix your own audio data. 676 | 677 | proc mixAudioFormat*(dst: ptr uint8; src: ptr uint8; 678 | format: AudioFormat; len: uint32; volume: cint) {. 679 | importc: "SDL_MixAudioFormat".} 680 | ## This works like `mixAudio()`, but you specify the audio format instead 681 | ## of using the format of audio device `1`. 682 | ## Thus it can be used when no audio device is open at all. 683 | 684 | proc lockAudio*() {.importc: "SDL_LockAudio".} 685 | ## Audio lock procedure. 686 | ## 687 | ## The lock manipulated by these procedures protects the callback procedure. 688 | ## During a `lockAudio()`/`unlockAudio()` pair, you can be guaranteed 689 | ## that the callback procedure is not running. Do not call these from the 690 | ## callback procedure or you will cause deadlock. 691 | 692 | proc lockAudioDevice*(dev: AudioDeviceID) {.importc: "SDL_LockAudioDevice".} 693 | ## Audio lock procedure. 694 | ## 695 | ## The lock manipulated by these procedures protects the callback procedure. 696 | ## During a `lockAudio()`/`unlockAudio()` pair, you can be guaranteed 697 | ## that the callback procedure is not running. Do not call these from the 698 | ## callback procedure or you will cause deadlock. 699 | 700 | proc unlockAudio*() {.importc: "SDL_UnlockAudio".} 701 | ## Audio unlock procedure. 702 | ## 703 | ## The lock manipulated by these procedures protects the callback procedure. 704 | ## During a `lockAudio()`/`unlockAudio()` pair, you can be guaranteed 705 | ## that the callback procedure is not running. Do not call these from the 706 | ## callback procedure or you will cause deadlock. 707 | 708 | proc unlockAudioDevice*(dev: AudioDeviceID) {.importc: "SDL_UnlockAudioDevice".} 709 | ## Audio unlock procedure. 710 | ## 711 | ## The lock manipulated by these procedures protects the callback procedure. 712 | ## During a `lockAudio()`/`unlockAudio()` pair, you can be guaranteed 713 | ## that the callback procedure is not running. Do not call these from the 714 | ## callback procedure or you will cause deadlock. 715 | 716 | proc closeAudio*() {.importc: "SDL_CloseAudio".} 717 | ## This procedure shuts down audio processing and closes the audio device. 718 | 719 | proc closeAudioDevice*(dev: AudioDeviceID) {.importc: "SDL_CloseAudioDevice".} 720 | ## This procedure shuts down audio processing and closes the audio device. 721 | 722 | 723 | proc newAudioStream*( 724 | src_format: AudioFormat; 725 | src_channels: uint8; 726 | src_rate: cint; 727 | dst_format: AudioFormat; 728 | dst_channels: uint8; 729 | dst_rate: cint): AudioStreamPtr {.importc: "SDL_NewAudioStream".} 730 | ## (Available since SDL 2.0.7) 731 | ## Create a new audio stream. return 0 on success, or -1 732 | ## on error. 733 | ## 734 | ## Parameters: 735 | ## * `src_format` The format of the source audio 736 | ## * `src_channels` The number of channels of the source audio 737 | ## * `src_rate` The sampling rate of the source audio 738 | ## * `dst_format` The format of the desired audio output 739 | ## * `dst_channels` The number of channels of the desired audio output 740 | ## * `dst_rate The` sampling rate of the desired audio output 741 | ## 742 | ## **See also:** 743 | ## * `AudioStreamPtr type<#AudioStreamPtr>`_ 744 | ## * `newAudioStream proc<#newAudioStream,AudioSpec,AudioSpec>`_ 745 | 746 | proc newAudioStream*(srcSpec, destSpec: AudioSpec): AudioStreamPtr = 747 | ## (Available since SDL 2.0.7) 748 | ## Create a new audio stream that converts from `srcSpec` to `destSpec`. 749 | ## 750 | ## **See also:** 751 | ## * `AudioStreamPtr type<#AudioStreamPtr>`_ 752 | ## * `newAudioStream proc<#newAudioStream,AudioFormat,uint8,cint,AudioFormat,uint8,cint>`_ 753 | newAudioStream( 754 | srcSpec.format, srcSpec.channels, srcSpec.freq, 755 | destSpec.format, destSpec.channels, destSpec.freq) 756 | 757 | proc put*( 758 | stream: AudioStreamPtr, 759 | buf: pointer, 760 | len: cint): cint {.importc: "SDL_AudioStreamPut".} 761 | ## (Available since SDL 2.0.7) 762 | ## Add data to be converted/resampled to the stream.Returns 0 on success, or -1 on error. 763 | ## 764 | ## Returns 0 on success, or -1 on error. 765 | ## 766 | ## Parameters: 767 | ## * `stream` The stream the audio data is being added to 768 | ## * `buf` A pointer to the audio data to add 769 | ## * `len` The number of bytes to write to the stream 770 | ## 771 | ## **See also:** 772 | ## * `AudioStreamPtr type<#AudioStreamPtr>`_ 773 | 774 | proc get*( 775 | stream: AudioStreamPtr, 776 | buf: pointer, 777 | len: cint): cint {.importc: "SDL_AudioStreamGet".} 778 | ## (Available since SDL 2.0.7) 779 | ## Get converted/resampled data from the stream. 780 | ## Returns the number of bytes read from the stream, or -1 on error. 781 | ## 782 | ## Parameters: 783 | ## * `stream` The stream the audio is being requested from 784 | ## * `buf` A buffer to fill with audio data 785 | ## * `len` The maximum number of bytes to fill 786 | ## 787 | ## **See also:** 788 | ## * `AudioStreamPtr type<#AudioStreamPtr>`_ 789 | 790 | proc available*(stream: AudioStreamPtr): cint {. 791 | importc: "SDL_AudioStreamAvailable".} 792 | ## (Available since SDL 2.0.7) 793 | ## Get the number of converted/resampled bytes available (BYTES, not samples!). 794 | ## The stream may be buffering data behind the scenes until it has enough to 795 | ## resample correctly, so this number might be lower than what you expect, or even 796 | ## be zero. Add more data or flush the stream if you need the data now. 797 | ## 798 | ## **See also:** 799 | ## * `AudioStreamPtr type<#AudioStreamPtr>`_ 800 | 801 | proc flush*(stream: AudioStreamPtr): cint {.importc: "SDL_AudioStreamFlush".} 802 | ## (Available since SDL 2.0.7) 803 | ## Tell the stream that you're done sending data, and anything being buffered 804 | ## should be converted/resampled and made available immediately. Returns 0 805 | ## on success, -1 on error. 806 | ## 807 | ## It is legal to add more data to a stream after flushing, but there will 808 | ## be audio gaps in the output. Generally this is intended to signal the 809 | ## end of input, so the complete output becomes available. 810 | ## 811 | ## **See also:** 812 | ## * `AudioStreamPtr type<#AudioStreamPtr>`_ 813 | 814 | proc clear*(stream: AudioStreamPtr) {.importc: "SDL_AudioStreamClear".} 815 | ## (Available since SDL 2.0.7) 816 | ## Clear any pending data in the stream without converting it. 817 | ## 818 | ## **See also:** 819 | ## * `AudioStreamPtr type<#AudioStreamPtr>`_ 820 | 821 | proc destroy*(stream: AudioStreamPtr) {.importc: "SDL_FreeAudioStream".} 822 | ## (Available since SDL 2.0.7) 823 | ## Free an audio stream. 824 | ## 825 | ## **See also:** 826 | ## * `AudioStreamPtr type<#AudioStreamPtr>`_ 827 | 828 | 829 | # vi: set ts=4 sw=4 expandtab: 830 | when not defined(SDL_Static): 831 | {.pop.} 832 | -------------------------------------------------------------------------------- /src/sdl2/gamecontroller.nim: -------------------------------------------------------------------------------- 1 | discard """ 2 | Simple DirectMedia Layer 3 | Copyright (C) 1997-2014 Sam Lantinga 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | """ 21 | 22 | 23 | ## SDL game controller event handling 24 | ## 25 | ## In order to use these functions, `sdl.init()` must have been called 26 | ## with the `SDL_INIT_JOYSTICK` flag. This causes SDL to scan the system 27 | ## for game controllers, and load appropriate drivers. 28 | ## 29 | ## If you would like to receive controller updates while the application 30 | ## is in the background, you should set the following hint before calling 31 | ## init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS 32 | 33 | import "../sdl2" 34 | import "joystick" 35 | 36 | 37 | type 38 | GameController* = object 39 | ## The gamecontroller structure used to identify an SDL game controller. 40 | 41 | GameControllerPtr* = ptr GameController 42 | 43 | GameControllerBindType* {.size: sizeof(cint).} = enum 44 | SDL_CONTROLLER_BINDTYPE_NONE, 45 | SDL_CONTROLLER_BINDTYPE_BUTTON, 46 | SDL_CONTROLLER_BINDTYPE_AXIS, 47 | SDL_CONTROLLER_BINDTYPE_HAT 48 | 49 | # Get the SDL joystick layer binding for this controller button/axis mapping 50 | 51 | type 52 | GameControllerButtonBind* = object 53 | ## Get the SDL joystick layer binding 54 | ## for this controller button/axis mapping 55 | case bindType*: GameControllerBindType 56 | of SDL_CONTROLLER_BINDTYPE_NONE: 57 | nil 58 | of SDL_CONTROLLER_BINDTYPE_BUTTON: 59 | button*: cint 60 | of SDL_CONTROLLER_BINDTYPE_AXIS: 61 | axis*: cint 62 | of SDL_CONTROLLER_BINDTYPE_HAT: 63 | hat*, hatMask*: cint 64 | 65 | when defined(SDL_Static): 66 | static: echo "SDL_Static option is deprecated and will soon be removed. Instead please use --dynlibOverride:SDL2." 67 | else: 68 | {.push callConv: cdecl, dynlib: LibName.} 69 | 70 | proc gameControllerAddMappingsFromRW*(rw: RWopsPtr, 71 | freerw: cint): cint {.importc: "SDL_GameControllerAddMappingsFromRW".} 72 | ## 73 | ## Load a set of Game Controller mappings from a seekable SDL data stream. 74 | ## 75 | ## You can call this function several times, if needed, to load different 76 | ## database files. 77 | ## 78 | ## If a new mapping is loaded for an already known controller GUID, the later 79 | ## version will overwrite the one currently loaded. 80 | ## 81 | ## Mappings not belonging to the current platform or with no platform field 82 | ## specified will be ignored (i.e. mappings for Linux will be ignored in 83 | ## Windows, etc). 84 | ## 85 | ## This function will load the text database entirely in memory before 86 | ## processing it, so take this into consideration if you are in a memory 87 | ## constrained environment. 88 | ## 89 | ## `Return` the number of mappings added or -1 on error 90 | 91 | proc gameControllerAddMappingsFromFile*(filename: cstring): cint = 92 | return gameControllerAddMappingsFromRW(rwFromFile(filename, "rb"), 1) 93 | ## Load a set of mappings from a file, filtered by the current `GetPlatform` 94 | ## 95 | ## Convenience macro. 96 | 97 | proc gameControllerAddMapping*(mappingString: cstring): cint {. 98 | importc: "SDL_GameControllerAddMapping".} 99 | ## Add or update an existing mapping configuration. 100 | ## 101 | ## `Return` `1` if mapping is added, `0` if updated, `-1` on error. 102 | 103 | proc gameControllerMappingForGUID*(guid: JoystickGuid): cstring {. 104 | importc: "SDL_GameControllerMappingForGUID".} 105 | ## Get a mapping string for a GUID. 106 | ## 107 | ## `Return` the mapping string. Must be freed with `sdl.free()`. 108 | ## Returns `nil` if no mapping is available 109 | 110 | proc mapping*(gameController: GameControllerPtr): cstring {. 111 | importc: "SDL_GameControllerMapping".} 112 | ## Get a mapping string for an open GameController. 113 | ## 114 | ## `Return` the mapping string. Must be freed with `sdl.free()`. 115 | ## Returns `nil` if no mapping is available 116 | 117 | proc isGameController*(joystickIndex: cint): Bool32 {. 118 | importc: "SDL_IsGameController".} 119 | ## Is the joystick on this index supported by the game controller interface? 120 | 121 | proc gameControllerNameForIndex*(joystickIndex: cint): cstring {. 122 | importc: "SDL_GameControllerNameForIndex".} 123 | ## Get the implementation dependent name of a game controller. 124 | ## 125 | ## This can be called before any controllers are opened. 126 | ## If no name can be found, this procedure returns `nil`. 127 | 128 | proc gameControllerOpen*(joystickIndex: cint): GameControllerPtr {. 129 | importc: "SDL_GameControllerOpen".} 130 | ## Open a game controller for use. 131 | ## 132 | ## The index passed as an argument refers to the N'th game controller 133 | ## on the system. 134 | ## 135 | ## This index is not the value which will identify this controller in future 136 | ## controller events. The joystick's instance id (`JoystickID`) will be 137 | ## used there instead. 138 | ## 139 | ## `Return` a controller identifier, or `nil` if an error occurred. 140 | 141 | proc gameControllerFromInstanceID*(joyid: JoystickID): GameControllerPtr {. 142 | importc: "SDL_GameControllerFromInstanceID".} 143 | ## Get the GameControllerPtr associated with an instance id. 144 | ## 145 | ## Returns an GameControllerPtr on success or `nil` on failure. 146 | 147 | proc name*(gameController: GameControllerPtr): cstring {. 148 | importc: "SDL_GameControllerName".} 149 | ## `Return` the name for this currently opened controller. 150 | 151 | proc getAttached*(gameController: GameControllerPtr): Bool32 {. 152 | importc: "SDL_GameControllerGetAttached".} 153 | ## `Returns` `true` if the controller has been opened and currently 154 | ## connected, or `false` if it has not. 155 | 156 | proc getJoystick*(gameController: GameControllerPtr): JoystickPtr {. 157 | importc: "SDL_GameControllerGetJoystick".} 158 | ## Get the underlying joystick object used by a controller. 159 | 160 | proc gameControllerEventState*(state: cint): cint {. 161 | importc: "SDL_GameControllerEventState".} 162 | ## Enable/disable controller event polling. 163 | ## 164 | ## If controller events are disabled, you must call 165 | ## `gameControllerUpdate()` yourself and check the state of the 166 | ## controller when you want controller information. 167 | ## 168 | ## The state can be one of `SDL_QUERY`, `SDL_ENABLE` or `SDL_IGNORE`. 169 | 170 | 171 | proc gameControllerUpdate*() {.importc: "SDL_GameControllerUpdate".} 172 | ## Update the current state of the open game controllers. 173 | ## 174 | ## This is called automatically by the event loop if any game controller 175 | ## events are enabled. 176 | 177 | type 178 | GameControllerAxis* {.size: sizeof(cint).} = enum 179 | ## The list of axes available from a controller. 180 | ## 181 | ## Thumbstick axis values range 182 | ## from `JOYSTICK_AXIS_MIN` to `JOYSTICK_AXIS_MAX`, 183 | ## and are centered within ~8000 of zero, 184 | ## though advanced UI will allow users to set 185 | ## or autodetect the dead zone, which varies between controllers. 186 | ## 187 | ## Trigger axis values range from `0` to `JOYSTICK_AXIS_MAX`. 188 | SDL_CONTROLLER_AXIS_INVALID = -1, 189 | SDL_CONTROLLER_AXIS_LEFTX, 190 | SDL_CONTROLLER_AXIS_LEFTY, 191 | SDL_CONTROLLER_AXIS_RIGHTX, 192 | SDL_CONTROLLER_AXIS_RIGHTY, 193 | SDL_CONTROLLER_AXIS_TRIGGERLEFT, 194 | SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 195 | SDL_CONTROLLER_AXIS_MAX 196 | 197 | converter toInt*(some: GameControllerAxis): uint8 = uint8(some) 198 | 199 | proc gameControllerGetAxisFromString*(pchString: cstring): GameControllerAxis {. 200 | importc: "SDL_GameControllerGetAxisFromString".} 201 | proc getAxisFromString*(pchString: cstring): GameControllerAxis {. 202 | importc: "SDL_GameControllerGetAxisFromString".} 203 | ## Turn this string into a axis mapping. 204 | 205 | proc gameControllerGetStringForAxis*(axis: GameControllerAxis): cstring {. 206 | importc: "SDL_GameControllerGetStringForAxis".} 207 | proc getStringForAxis*(axis: GameControllerAxis): cstring {. 208 | importc: "SDL_GameControllerGetStringForAxis".} 209 | ## Turn this axis enum into a string mapping. 210 | 211 | proc getBindForAxis*(gameController: GameControllerPtr, 212 | axis: GameControllerAxis): GameControllerButtonBind {. 213 | importc: "SDL_GameControllerGetBindForAxis".} 214 | ## Get the SDL joystick layer binding for this controller button mapping. 215 | 216 | proc getAxis*(gameController: GameControllerPtr, 217 | axis: GameControllerAxis): int16 {. 218 | importc: "SDL_GameControllerGetAxis".} 219 | ## Get the current state of an axis control on a game controller. 220 | ## 221 | ## The state is a value ranging from `-32768` to `32767` 222 | ## (except for the triggers, which range from `0` to `32767`. 223 | ## 224 | ## The axis indices start at index `0`. 225 | 226 | type 227 | GameControllerButton* {.size: sizeof(cint).} = enum 228 | ## The list of buttons available from a controller 229 | SDL_CONTROLLER_BUTTON_INVALID = -1, 230 | SDL_CONTROLLER_BUTTON_A, 231 | SDL_CONTROLLER_BUTTON_B, 232 | SDL_CONTROLLER_BUTTON_X, 233 | SDL_CONTROLLER_BUTTON_Y, 234 | SDL_CONTROLLER_BUTTON_BACK, 235 | SDL_CONTROLLER_BUTTON_GUIDE, 236 | SDL_CONTROLLER_BUTTON_START, 237 | SDL_CONTROLLER_BUTTON_LEFTSTICK, 238 | SDL_CONTROLLER_BUTTON_RIGHTSTICK, 239 | SDL_CONTROLLER_BUTTON_LEFTSHOULDER, 240 | SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, 241 | SDL_CONTROLLER_BUTTON_DPAD_UP, 242 | SDL_CONTROLLER_BUTTON_DPAD_DOWN, 243 | SDL_CONTROLLER_BUTTON_DPAD_LEFT, 244 | SDL_CONTROLLER_BUTTON_DPAD_RIGHT, 245 | SDL_CONTROLLER_BUTTON_MAX 246 | 247 | converter toInt*(some: GameControllerButton): uint8 = uint8(some) 248 | 249 | proc gameControllerGetButtonFromString*( 250 | pchString: cstring): GameControllerButton {. 251 | importc: "SDL_GameControllerGetButtonFromString".} 252 | proc getButtonFromString*(pchString: cstring): GameControllerButton {. 253 | importc: "SDL_GameControllerGetButtonFromString".} 254 | ## Turn this string into a button mapping. 255 | 256 | proc gameControllerGetStringForButton*( 257 | button: GameControllerButton): cstring {. 258 | importc: "SDL_GameControllerGetStringForButton".} 259 | proc getStringForButton*(button: GameControllerButton): cstring {. 260 | importc: "SDL_GameControllerGetStringForButton".} 261 | ## Turn this button enum into a string mapping. 262 | 263 | proc getBindForButton*( 264 | gameController: GameControllerPtr, 265 | button: GameControllerButton): GameControllerButtonBind {. 266 | importc: "SDL_GameControllerGetBindForButton".} 267 | ## Get the SDL joystick layer binding for this controller button mapping. 268 | 269 | proc getButton*( 270 | gameController: GameControllerPtr, 271 | button: GameControllerButton): uint8 {. 272 | importc: "SDL_GameControllerGetButton".} 273 | ## Get the current state of a button on a game controller. 274 | ## 275 | ## The button indices start at index `0`. 276 | 277 | proc gameControllerRumble*(gamecontroller: GameControllerPtr, 278 | lowFrequencyRumble, highFrequencyRUmble: uint16, 279 | durationMs: uint32): SDL_Return {. 280 | importc: "SDL_GameControllerRumble".} 281 | ## 282 | ## Start a rumble effect on a game controller. 283 | ## 284 | ## Each call to this function cancels any previous rumble effect, and calling 285 | ## it with 0 intensity stops any rumbling. 286 | ## 287 | ## `Returns` 0, or -1 if rumble isn't supported on this controller 288 | 289 | proc gameControllerRumbleTriggers*(gamecontroller: GameControllerPtr, 290 | leftRumble, rightRue: uint16, durationMs: uint32): cint {. 291 | importc: "SDL_GameControllerRumbleTriggers".} 292 | ## Start a rumble effect in the game controller's triggers. 293 | ## 294 | ## Each call to this function cancels any previous trigger rumble effect, and 295 | ## calling it with 0 intensity stops any rumbling. 296 | ## 297 | ## Note that this is rumbling of the _triggers_ and not the game controller as 298 | ## a whole. This is currently only supported on Xbox One controllers. If you 299 | ## want the (more common) whole-controller rumble, use 300 | ## `gameControllerRumble` instead. 301 | ## 302 | ## `Returns` 0, or -1 if trigger rumble isn't supported on this controller 303 | 304 | proc gameControllerHasLED*(gamecontroller: GameControllerPtr): Bool32 {. 305 | importc: "SDL_GameControllerHasLED".} 306 | ## Query whether a game controller has an LED. 307 | ## 308 | ## \returns SDL_TRUE, or SDL_FALSE if this controller does not have a 309 | ## modifiable LED 310 | 311 | proc gameControllerHasRumble*(gamecontroller: GameControllerPtr): Bool32 {. 312 | importc: "SDL_GameControllerHasRumble".} 313 | ## Query whether a game controller has rumble support. 314 | ## 315 | ## `Returns` `True32`, or `False32` if this controller does not have rumble 316 | ## support 317 | 318 | proc gameControllerHasRumbleTriggers*(gamecontroller: GameControllerPtr) {. 319 | importc: "SDL_GameControllerHasRumbleTriggers".} 320 | ## Query whether a game controller has rumble support on triggers. 321 | ## 322 | ## `Returns` `True32`, or `False32` if this controller does not have trigger 323 | ## rumble support 324 | 325 | proc gameControllerSetLED*(gamecontroller: GameControllerPtr, red, green, 326 | blue: uint8) {. 327 | importc: "SDL_GameControllerSetLED".} 328 | ## Update a game controller's LED color. 329 | ## 330 | ## `Returns` 0, or -1 if this controller does not have a modifiable LED 331 | 332 | proc gameControllerSendEffect*(gamecontroller: GameControllerPtr, data: pointer, 333 | size: cint): cint {. 334 | importc: "SDL_GameControllerSendEffect".} 335 | ## Send a controller specific effect packet 336 | ## 337 | ## `Returns` 0, or -1 if this controller or driver doesn't support effect 338 | ## packets 339 | 340 | proc gameControllerGetAppleSFSymbolsNameForButton*( 341 | gamecontroller: GameControllerPtr, button: GameControllerButton): cstring {. 342 | importc: "SDL_GameControllerGetAppleSFSymbolsNameForButton".} 343 | ## Return the sfSymbolsName for a given button on a game controller on Apple 344 | ## platforms. 345 | ## 346 | ## `Returns` the sfSymbolsName or `nil` if the name can't be found 347 | 348 | 349 | proc gameControllerGetAppleSFSymbolsNameForAxis*( 350 | gamecontroller: GameControllerPtr, axis: GameControllerAxis): cstring {. 351 | importc: "SDL_GameControllerGetAppleSFSymbolsNameForAxis".} 352 | ## Return the sfSymbolsName for a given axis on a game controller on Apple 353 | ## platforms. 354 | ## 355 | ## `Returns` the sfSymbolsName or `nil` if the name can't be found 356 | 357 | proc close*(gameController: GameControllerPtr) {. 358 | importc: "SDL_GameControllerClose".} 359 | ## Close a controller previously opened with `gameControllerOpen()`. 360 | 361 | 362 | when not defined(SDL_Static): 363 | {.pop.} 364 | -------------------------------------------------------------------------------- /src/sdl2/gfx.nim: -------------------------------------------------------------------------------- 1 | # SDL2_gfxPrimitives.h: graphics primitives for SDL 2 | # 3 | # Copyright (C) 2012 Andreas Schiffler 4 | # 5 | # This software is provided 'as-is', without any express or implied 6 | # warranty. In no event will the authors be held liable for any damages 7 | # arising from the use of this software. 8 | # 9 | # Permission is granted to anyone to use this software for any purpose, 10 | # including commercial applications, and to alter it and redistribute it 11 | # freely, subject to the following restrictions: 12 | # 13 | # 1. The origin of this software must not be misrepresented; you must not 14 | # claim that you wrote the original software. If you use this software 15 | # in a product, an acknowledgment in the product documentation would be 16 | # appreciated but is not required. 17 | # 18 | # 2. Altered source versions must be plainly marked as such, and must not be 19 | # misrepresented as being the original software. 20 | # 21 | # 3. This notice may not be removed or altered from any source 22 | # distribution. 23 | # 24 | # Andreas Schiffler -- aschiffler at ferzkopp dot net 25 | # 26 | # 27 | 28 | # Docs: http://www.ferzkopp.net/Software/SDL_gfx-2.0/Docs/html/_s_d_l__gfx_primitives_8c.html 29 | 30 | import sdl2 31 | 32 | when not defined(SDL_Static): 33 | when defined(windows): 34 | const LibName = "SDL2_gfx.dll" 35 | elif defined(macosx): 36 | const LibName = "libSDL2_gfx.dylib" 37 | else: 38 | const LibName = "libSDL2_gfx(|-1.0).so(|.0)" 39 | else: 40 | static: echo "SDL_Static option is deprecated and will soon be removed. Instead please use --dynlibOverride:SDL2_gfx." 41 | 42 | const 43 | FPS_UPPER_LIMIT* = 200 44 | ## Highest possible rate supported by framerate controller in Hz (1/s). 45 | FPS_LOWER_LIMIT* = 1 46 | ## Lowest possible rate supported by framerate controller in Hz (1/s). 47 | FPS_DEFAULT* = 30 48 | ## Default rate of framerate controller in Hz (1/s). 49 | 50 | 51 | type 52 | FpsManager* {.pure, final.} = object 53 | ## Object holding the state and timing information 54 | ## of the framerate controller. 55 | framecount*: cint 56 | rateticks*: cfloat 57 | baseticks*: cint 58 | lastticks*: cint 59 | rate*: cint 60 | 61 | {.pragma: i, importc, discardable.} 62 | 63 | when not defined(SDL_Static): 64 | {.push callConv:cdecl, dynlib: LibName.} 65 | 66 | proc pixelColor*(renderer: RendererPtr; x, y: int16; 67 | color: uint32): SDL_Return {.importc, discardable.} 68 | ## Pixel draw with alpha blending enabled if `a` < `255`. 69 | ## 70 | ## `x`, `y` Coordinates of the pixel. 71 | 72 | proc pixelRGBA*(renderer: RendererPtr; x: int16; y: int16; r: uint8; g: uint8; 73 | b: uint8; a: uint8): SDL_Return {.importc, discardable.} 74 | ## Pixel draw with alpha blending enabled if `a` < `255`. 75 | ## 76 | ## `x`, `y` Coordinates of the pixel. 77 | 78 | # Horizontal line 79 | proc hlineColor*(renderer: RendererPtr; x1: int16; x2: int16; y: int16; 80 | color: uint32): SDL_Return {.importc, discardable.} 81 | ## Draw horizontal line with alpha blending. 82 | ## 83 | ## `x1` X coordinate of the first point (i.e. left) of the line. 84 | ## 85 | ## `x2` X coordinate of the second point (i.e. right) of the line. 86 | ## 87 | ## `y` Y coordinate of the points of the line. 88 | 89 | proc hlineRGBA*(renderer: RendererPtr; x1: int16; x2: int16; y: int16; 90 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 91 | ## Draw horizontal line with alpha blending. 92 | ## 93 | ## `x1` X coordinate of the first point (i.e. left) of the line. 94 | ## 95 | ## `x2` X coordinate of the second point (i.e. right) of the line. 96 | ## 97 | ## `y` Y coordinate of the points of the line. 98 | 99 | # Vertical line 100 | proc vlineColor*(renderer: RendererPtr; x, y1, y2: int16; 101 | color: uint32): SDL_Return {.importc, discardable.} 102 | ## Draw vertical line with alpha blending. 103 | ## 104 | ## `x` X coordinate of the points of the line. 105 | ## 106 | ## `y1` Y coordinate of the first point (i.e. top) of the line. 107 | ## 108 | ## `y2` Y coordinate of the second point (i.e. bottom) of the line. 109 | 110 | proc vlineRGBA*(renderer: RendererPtr; x, y1, y2: int16; 111 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 112 | ## Draw vertical line with alpha blending. 113 | ## 114 | ## `x` X coordinate of the points of the line. 115 | ## 116 | ## `y1` Y coordinate of the first point (i.e. top) of the line. 117 | ## 118 | ## `y2` Y coordinate of the second point (i.e. bottom) of the line. 119 | 120 | # Rectangle 121 | proc rectangleColor*(renderer: RendererPtr; x1, y1, x2, y2: int16; 122 | color: uint32): SDL_Return {.importc, discardable.} 123 | ## Draw rectangle with alpha blending. 124 | ## 125 | ## `x1`, `y1` Coordinates of the first point (i.e. top right) 126 | ## of the rectangle. 127 | ## 128 | ## `x2`, `y2` Coordinates of the second point (i.e. bottom left) 129 | ## of the rectangle. 130 | 131 | proc rectangleRGBA*(renderer: RendererPtr; x1, y1, x2, y2: int16; 132 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 133 | ## Draw rectangle with alpha blending. 134 | ## 135 | ## `x1`, `y1` Coordinates of the first point (i.e. top right) 136 | ## of the rectangle. 137 | ## 138 | ## `x2`, `y2` Coordinates of the second point (i.e. bottom left) 139 | ## of the rectangle. 140 | 141 | # Rounded-Corner Rectangle 142 | proc roundedRectangleColor*(renderer: RendererPtr; x1, y1, x2, y2, rad: int16; 143 | color: uint32): SDL_Return {.importc, discardable.} 144 | ## Draw rounded-corner rectangle with alpha blending. 145 | ## 146 | ## `x1`, `y1` Coordinates of the first point (i.e. top right) 147 | ## of the rectangle. 148 | ## 149 | ## `x2`, `y2` Coordinates of the second point (i.e. bottom left) 150 | ## of the rectangle. 151 | ## 152 | ## `rad` The radius of the corner arc. 153 | 154 | proc roundedRectangleRGBA*(renderer: RendererPtr; x1, y1, x2, y2, rad: int16; 155 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 156 | ## Draw rounded-corner rectangle with alpha blending. 157 | ## 158 | ## `x1`, `y1` Coordinates of the first point (i.e. top right) 159 | ## of the rectangle. 160 | ## 161 | ## `x2`, `y2` Coordinates of the second point (i.e. bottom left) 162 | ## of the rectangle. 163 | ## 164 | ## `rad` The radius of the corner arc. 165 | 166 | # Filled rectangle (Box) 167 | proc boxColor*(renderer: RendererPtr; x1, y1, x2, y2: int16; 168 | color: uint32): SDL_Return {.importc, discardable.} 169 | ## Draw box (filled rectangle) with alpha blending. 170 | ## 171 | ## `x1`, `y1` Coordinates of the first point (i.e. top right) 172 | ## of the box. 173 | ## 174 | ## `x2`, `y2` Coordinates of the second point (i.e. bottom left) 175 | ## of the box. 176 | 177 | proc boxRGBA*(renderer: RendererPtr; x1, y1, x2, y2: int16; 178 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 179 | ## Draw box (filled rectangle) with alpha blending. 180 | ## 181 | ## `x1`, `y1` Coordinates of the first point (i.e. top right) 182 | ## of the box. 183 | ## 184 | ## `x2`, `y2` Coordinates of the second point (i.e. bottom left) 185 | ## of the box. 186 | 187 | # Rounded-Corner Filled rectangle (Box) 188 | proc roundedBoxColor*(renderer: RendererPtr; x1, y1, x2, y2, rad: int16; 189 | color: uint32): SDL_Return {.importc, discardable.} 190 | ## Draw rounded-corner box (filled rectangle) with alpha blending. 191 | ## 192 | ## `x1`, `y1` Coordinates of the first point (i.e. top right) 193 | ## of the box. 194 | ## 195 | ## `x2`, `y2` Coordinates of the second point (i.e. bottom left) 196 | ## of the box. 197 | ## 198 | ## `rad` The radius of the cornder arcs of the box. 199 | 200 | proc roundedBoxRGBA*(renderer: RendererPtr; x1, y1, x2, y2, rad: int16; 201 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 202 | ## Draw rounded-corner box (filled rectangle) with alpha blending. 203 | ## 204 | ## `x1`, `y1` Coordinates of the first point (i.e. top right) 205 | ## of the box. 206 | ## 207 | ## `x2`, `y2` Coordinates of the second point (i.e. bottom left) 208 | ## of the box. 209 | ## 210 | ## `rad` The radius of the cornder arcs of the box. 211 | 212 | # Line 213 | proc lineColor*(renderer: RendererPtr; x1, y1, x2, y2: int16; 214 | color: uint32): SDL_Return {.importc, discardable.} 215 | ## Draw line with alpha blending. 216 | ## 217 | ## `x1`, `y1` Coordinates of the first point of the line. 218 | ## 219 | ## `x2`, `y2` Coordinates of the second point of the line. 220 | 221 | proc lineRGBA*(renderer: RendererPtr; x1, y1, x2, y2: int16; 222 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 223 | ## Draw line with alpha blending. 224 | ## 225 | ## `x1`, `y1` Coordinates of the first point of the line. 226 | ## 227 | ## `x2`, `y2` Coordinates of the second point of the line. 228 | 229 | # AA Line 230 | proc aalineColor*(renderer: RendererPtr; 231 | x1: int16; y1: int16; 232 | x2: int16; y2: int16; 233 | color: uint32): SDL_Return {.importc, discardable.} 234 | ## Draw anti-aliased line with alpha blending. 235 | ## 236 | ## `x1`, `y1` Coordinates of the first point of the aa-line. 237 | ## 238 | ## `x2`, `y2` Coordinates of the second point of the aa-line. 239 | 240 | proc aalineRGBA*(renderer: RendererPtr; x1: int16; y1: int16; 241 | x2: int16; y2: int16; r: uint8; g: uint8; b: uint8; 242 | a: uint8): SDL_Return {.importc, discardable.} 243 | ## Draw anti-aliased line with alpha blending. 244 | ## 245 | ## `x1`, `y1` Coordinates of the first point of the aa-line. 246 | ## 247 | ## `x2`, `y2` Coordinates of the second point of the aa-line. 248 | 249 | # Thick Line 250 | proc thickLineColor*(renderer: RendererPtr; x1, y1, x2, y2: int16; 251 | width: uint8; color: uint32): SDL_Return {.importc, discardable.} 252 | ## Draw thick line with alpha blending. 253 | ## 254 | ## `x1`, `y1` Coordinates of the first point of the line. 255 | ## 256 | ## `x2`, `y2` Coordinates of the second point of the line. 257 | ## 258 | ## `width` Width of the line in pixels. Must be `>0`. 259 | 260 | proc thickLineRGBA*(renderer: RendererPtr; x1, y1, x2, y2: int16; 261 | width, r, g, b, a: uint8): SDL_Return {.importc, discardable.} 262 | ## Draw thick line with alpha blending. 263 | ## 264 | ## `x1`, `y1` Coordinates of the first point of the line. 265 | ## 266 | ## `x2`, `y2` Coordinates of the second point of the line. 267 | ## 268 | ## `width` Width of the line in pixels. Must be `>0`. 269 | 270 | # Circle 271 | proc circleColor*(renderer: RendererPtr; x, y, rad: int16; 272 | color: uint32): SDL_Return {.importc, discardable.} 273 | ## Draw circle with alpha blending. 274 | ## 275 | ## `x`, `y` Coordinates of the center of the circle. 276 | ## 277 | ## `rad` Radius in pixels of the circle. 278 | 279 | proc circleRGBA*(renderer: RendererPtr; x, y, rad: int16; 280 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 281 | ## Draw circle with alpha blending. 282 | ## 283 | ## `x`, `y` Coordinates of the center of the circle. 284 | ## 285 | ## `rad` Radius in pixels of the circle. 286 | 287 | # Arc 288 | proc arcColor*(renderer: RendererPtr; x, y, rad, start, finish: int16; 289 | color: uint32): SDL_Return {.importc, discardable.} 290 | ## Draw arc with alpha blending. 291 | ## 292 | ## `x`, `y` Coordinates of the center of the arc. 293 | ## 294 | ## `rad` Radius in pixels of the arc. 295 | ## 296 | ## `start`, `end` Starting and ending radius in degrees of the arc. 297 | ## `0` degrees is down, increasing counterclockwise. 298 | 299 | proc arcRGBA*(renderer: RendererPtr; x, y, rad, start, finish: int16; 300 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 301 | ## Draw arc with alpha blending. 302 | ## 303 | ## `x`, `y` Coordinates of the center of the arc. 304 | ## 305 | ## `rad` Radius in pixels of the arc. 306 | ## 307 | ## `start`, `end` Starting and ending radius in degrees of the arc. 308 | ## `0` degrees is down, increasing counterclockwise. 309 | 310 | # AA Circle 311 | proc aacircleColor*(renderer: RendererPtr; x, y, rad: int16; 312 | color: uint32): SDL_Return {.importc, discardable.} 313 | ## Draw anti-aliased circle with alpha blending. 314 | ## 315 | ## `x`, `y` Coordinates of the center of the aa-circle. 316 | ## 317 | ## `rad` Radius in pixels of the aa-circle. 318 | 319 | proc aacircleRGBA*(renderer: RendererPtr; x, y, rad: int16; 320 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 321 | ## Draw anti-aliased circle with alpha blending. 322 | ## 323 | ## `x`, `y` Coordinates of the center of the aa-circle. 324 | ## 325 | ## `rad` Radius in pixels of the aa-circle. 326 | 327 | # Filled Circle 328 | proc filledCircleColor*(renderer: RendererPtr; x, y, r: int16; 329 | color: uint32): SDL_Return {.importc, discardable.} 330 | ## Draw filled circle with alpha blending. 331 | ## 332 | ## `x`, `y` Coordinates of the center of the filled circle. 333 | ## 334 | ## `rad` Radius in pixels of the filled circle. 335 | 336 | proc filledCircleRGBA*(renderer: RendererPtr; x, y, rad: int16; 337 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 338 | ## Draw filled circle with alpha blending. 339 | ## 340 | ## `x`, `y` Coordinates of the center of the filled circle. 341 | ## 342 | ## `rad` Radius in pixels of the filled circle. 343 | 344 | # Ellipse 345 | proc ellipseColor*(renderer: RendererPtr; x: int16; y: int16; 346 | rx: int16; ry: int16; 347 | color: uint32): SDL_Return {.importc, discardable.} 348 | ## Draw ellipse with alpha blending. 349 | ## 350 | ## `x`, `y` Coordinates of the center of the ellipse. 351 | ## 352 | ## `rx` Horizontal radius in pixels of the ellipse. 353 | ## 354 | ## `ry` Vertical radius in pixels of the ellipse. 355 | 356 | proc ellipseRGBA*(renderer: RendererPtr; x: int16; y: int16; 357 | rx: int16; ry: int16; r: uint8; g: uint8; b: uint8; 358 | a: uint8): SDL_Return {.importc, discardable.} 359 | ## Draw ellipse with alpha blending. 360 | ## 361 | ## `x`, `y` Coordinates of the center of the ellipse. 362 | ## 363 | ## `rx` Horizontal radius in pixels of the ellipse. 364 | ## 365 | ## `ry` Vertical radius in pixels of the ellipse. 366 | 367 | # AA Ellipse 368 | proc aaellipseColor*(renderer: RendererPtr; x, y, rx, ry: int16; 369 | color: uint32): SDL_Return {.importc, discardable.} 370 | ## Draw anti-aliased ellipse with alpha blending. 371 | ## 372 | ## `x`, `y` Coordinates of the center of the aa-ellipse. 373 | ## 374 | ## `rx` Horizontal radius in pixels of the aa-ellipse. 375 | ## 376 | ## `ry` Vertical radius in pixels of the aa-ellipse. 377 | 378 | proc aaellipseRGBA*(renderer: RendererPtr; x, y, rx, ry: int16; 379 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 380 | ## Draw anti-aliased ellipse with alpha blending. 381 | ## 382 | ## `x`, `y` Coordinates of the center of the aa-ellipse. 383 | ## 384 | ## `rx` Horizontal radius in pixels of the aa-ellipse. 385 | ## 386 | ## `ry` Vertical radius in pixels of the aa-ellipse. 387 | 388 | # Filled Ellipse 389 | proc filledEllipseColor*(renderer: RendererPtr; x, y, rx, ry: int16; 390 | color: uint32): SDL_Return {.importc, discardable.} 391 | ## Draw filled ellipse with alpha blending. 392 | ## 393 | ## `x`, `y` Coordinates of the center of the filled ellipse. 394 | ## 395 | ## `rx` Horizontal radius in pixels of the filled ellipse. 396 | ## 397 | ## `ry` Vertical radius in pixels of the filled ellipse. 398 | 399 | proc filledEllipseRGBA*(renderer: RendererPtr; x, y, rx, ry: int16; 400 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 401 | ## Draw filled ellipse with alpha blending. 402 | ## 403 | ## `x`, `y` Coordinates of the center of the filled ellipse. 404 | ## 405 | ## `rx` Horizontal radius in pixels of the filled ellipse. 406 | ## 407 | ## `ry` Vertical radius in pixels of the filled ellipse. 408 | 409 | # Pie 410 | proc pieColor*(renderer: RendererPtr; x, y, rad, start, finish: int16; 411 | color: uint32): SDL_Return {.importc, discardable.} 412 | ## Draw pie (outline) with alpha blending. 413 | ## 414 | ## `x`, `y` Coordinates of the center of the pie. 415 | ## 416 | ## `rad` Radius in pixels of the pie. 417 | ## 418 | ## `start`, `end` Starting and ending radius in degrees of the pie. 419 | 420 | proc pieRGBA*(renderer: RendererPtr; x, y, rad, start, finish: int16; 421 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 422 | ## Draw pie (outline) with alpha blending. 423 | ## 424 | ## `x`, `y` Coordinates of the center of the pie. 425 | ## 426 | ## `rad` Radius in pixels of the pie. 427 | ## 428 | ## `start`, `end` Starting and ending radius in degrees of the pie. 429 | 430 | # Filled Pie 431 | proc filledPieColor*(renderer: RendererPtr; x, y, rad, start, finish: int16; 432 | color: uint32): SDL_Return {.importc, discardable.} 433 | ## Draw filled pie with alpha blending. 434 | ## 435 | ## `x`, `y` Coordinates of the center of the filled pie. 436 | ## 437 | ## `rad` Radius in pixels of the filled pie. 438 | ## 439 | ## `start`, `end` Starting and ending radius in degrees 440 | ## of the filled pie. 441 | 442 | proc filledPieRGBA*(renderer: RendererPtr; x, y, rad, start, finish: int16; 443 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 444 | ## Draw filled pie with alpha blending. 445 | ## 446 | ## `x`, `y` Coordinates of the center of the filled pie. 447 | ## 448 | ## `rad` Radius in pixels of the filled pie. 449 | ## 450 | ## `start`, `end` Starting and ending radius in degrees 451 | ## of the filled pie. 452 | 453 | # Trigon 454 | proc trigonColor*(renderer: RendererPtr; x1,y1,x2,y2,x3,y3: int16, 455 | color: uint32): SDL_Return {.importc, discardable.} 456 | ## Draw trigon (triangle outline) with alpha blending. 457 | ## 458 | ## `x1`, `y1` Coordinates of the first point of the trigon. 459 | ## 460 | ## `x2`, `y2` Coordinates of the second point of the trigon. 461 | ## 462 | ## `x3`, `y3` Coordinates of the third point of the trigon. 463 | 464 | proc trigonRGBA*(renderer: RendererPtr; x1, y1, x2, y2, x3, y3: int16; 465 | r,g,b,a: uint8): SDL_Return {.importc, discardable.} 466 | ## Draw trigon (triangle outline) with alpha blending. 467 | ## 468 | ## `x1`, `y1` Coordinates of the first point of the trigon. 469 | ## 470 | ## `x2`, `y2` Coordinates of the second point of the trigon. 471 | ## 472 | ## `x3`, `y3` Coordinates of the third point of the trigon. 473 | 474 | # AA-Trigon 475 | proc aaTrigonColor*(renderer: RendererPtr; x1, y1, x2, y2, x3, y3: int16; 476 | color: uint32): SDL_Return {.importc: "aatrigonColor", 477 | discardable.} 478 | ## Draw anti-aliased trigon (triangle outline) with alpha blending. 479 | ## 480 | ## `x1`, `y1` Coordinates of the first point of the aa-trigon. 481 | ## 482 | ## `x2`, `y2` Coordinates of the second point of the aa-trigon. 483 | ## 484 | ## `x3`, `y3` Coordinates of the third point of the aa-trigon. 485 | 486 | proc aaTrigonRGBA*(renderer: RendererPtr; x1, y1, x2, y2, x3, y3: int16; 487 | r, g, b, a: uint8): SDL_Return {.importc: "aatrigonRGBA", discardable.} 488 | ## Draw anti-aliased trigon (triangle outline) with alpha blending. 489 | ## 490 | ## `x1`, `y1` Coordinates of the first point of the aa-trigon. 491 | ## 492 | ## `x2`, `y2` Coordinates of the second point of the aa-trigon. 493 | ## 494 | ## `x3`, `y3` Coordinates of the third point of the aa-trigon. 495 | 496 | # Filled Trigon 497 | proc filledTrigonColor*(renderer: RendererPtr; x1: int16; y1: int16; 498 | x2: int16; y2: int16; x3: int16; y3: int16; 499 | color: uint32): SDL_Return {.importc, discardable.} 500 | ## Draw filled trigon (triangle) with alpha blending. 501 | ## 502 | ## `x1`, `y1` Coordinates of the first point of the filled trigon. 503 | ## 504 | ## `x2`, `y2` Coordinates of the first point of the filled trigon. 505 | ## 506 | ## `x3`, `y3` Coordinates of the first point of the filled trigon. 507 | 508 | proc filledTrigonRGBA*(renderer: RendererPtr; x1: int16; y1: int16; 509 | x2: int16; y2: int16; x3: int16; y3: int16; 510 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 511 | ## Draw filled trigon (triangle) with alpha blending. 512 | ## 513 | ## `x1`, `y1` Coordinates of the first point of the filled trigon. 514 | ## 515 | ## `x2`, `y2` Coordinates of the first point of the filled trigon. 516 | ## 517 | ## `x3`, `y3` Coordinates of the first point of the filled trigon. 518 | 519 | # Polygon 520 | proc polygonColor*(renderer: RendererPtr; vx: ptr int16; vy: ptr int16; 521 | n: cint; color: uint32): SDL_Return {.importc, discardable.} 522 | ## Draw polygon with alpha blending. 523 | ## 524 | ## `vx`, `vy` Vertex arrays containing coordinates of the points 525 | ## of the polygon. 526 | ## 527 | ## `n` Number of points in the vertex array. Minimum number is `3`. 528 | 529 | proc polygonRGBA*(renderer: RendererPtr; vx: ptr int16; vy: ptr int16; 530 | n: cint; r, g, b, a: uint8): SDL_Return {.importc, discardable.} 531 | ## Draw polygon with alpha blending. 532 | ## 533 | ## `vx`, `vy` Vertex arrays containing coordinates of the points 534 | ## of the polygon. 535 | ## 536 | ## `n` Number of points in the vertex array. Minimum number is `3`. 537 | 538 | # AA-Polygon 539 | proc aaPolygonColor*(renderer: RendererPtr; vx: ptr int16; vy: ptr int16; 540 | n: cint; color: uint32): SDL_Return {. 541 | importc: "aapolygonColor", discardable.} 542 | ## Draw anti-aliased polygon with alpha blending. 543 | ## 544 | ## `vx`, `vy` Vertex arrays containing coordinates of the points 545 | ## of the aa-polygon. 546 | ## 547 | ## `n` Number of points in the vertex array. Minimum number is `3`. 548 | 549 | proc aaPolygonRGBA*(renderer: RendererPtr; vx: ptr int16; vy: ptr int16; 550 | n: cint; r,g,b,a: uint8): SDL_Return {. 551 | importc: "aapolygonRGBA", discardable.} 552 | ## Draw anti-aliased polygon with alpha blending. 553 | ## 554 | ## `vx`, `vy` Vertex arrays containing coordinates of the points 555 | ## of the aa-polygon. 556 | ## 557 | ## `n` Number of points in the vertex array. Minimum number is `3`. 558 | 559 | # Filled Polygon 560 | proc filledPolygonColor*(renderer: RendererPtr; vx: ptr int16; 561 | vy: ptr int16; n: cint; 562 | color: uint32): SDL_Return {.importc, discardable.} 563 | ## Draw filled polygon with alpha blending. 564 | ## 565 | ## `vx`, `vy` Vertex arrays containing coordinates of the points 566 | ## of the filled polygon. 567 | ## 568 | ## `n` Number of points in the vertex array. Minimum number is `3`. 569 | 570 | proc filledPolygonRGBA*(renderer: RendererPtr; vx: ptr int16; 571 | vy: ptr int16; n: cint; r: uint8; g: uint8; b: uint8; 572 | a: uint8): SDL_Return {.importc, discardable.} 573 | ## Draw filled polygon with alpha blending. 574 | ## 575 | ## `vx`, `vy` Vertex arrays containing coordinates of the points 576 | ## of the filled polygon. 577 | ## 578 | ## `n` Number of points in the vertex array. Minimum number is `3`. 579 | 580 | # Textured Polygon 581 | proc texturedPolygon*(renderer: RendererPtr; vx: ptr int16; 582 | vy: ptr int16; n: cint; texture: SurfacePtr; 583 | texture_dx: cint; 584 | texture_dy: cint): SDL_Return {.importc, discardable.} 585 | ## Draw polygon filled with the given texture. 586 | ## 587 | ## `vx`, `vy` Vertex arrays containing coordinates of the points 588 | ## of the textured polygon. 589 | ## 590 | ## `n` Number of points in the vertex array. Minimum number is `3`. 591 | ## 592 | ## `texture` The `sdl.Surface` to use to fill the polygon. 593 | ## 594 | ## `texture_dx`, `texture_dy` The offset of the texture 595 | ## relative to the screen. If you move the polygon `10` pixels to the left 596 | ## and want the texture to appear the same, you need to increase 597 | ## the `texture_dx` value. 598 | 599 | # Bezier 600 | proc bezierColor*(renderer: RendererPtr; vx,vy: ptr int16; 601 | n: cint; s: cint; 602 | color: uint32): SDL_Return {.importc, discardable.} 603 | ## Draw a bezier curve with alpha blending. 604 | ## 605 | ## `vx`, `vy` Vertex arrays containing coordinates of the points 606 | ## of the bezier curve. 607 | ## 608 | ## `n` Number of points in the vertex array. Minimum number is `3`. 609 | ## 610 | ## `s` Number of steps for the interpolation. Minimum number is `2`. 611 | 612 | proc bezierRGBA*(renderer: RendererPtr; vx, vy: ptr int16; 613 | n: cint; s: cint; 614 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 615 | ## Draw a bezier curve with alpha blending. 616 | ## 617 | ## `vx`, `vy` Vertex arrays containing coordinates of the points 618 | ## of the bezier curve. 619 | ## 620 | ## `n` Number of points in the vertex array. Minimum number is `3`. 621 | ## 622 | ## `s` Number of steps for the interpolation. Minimum number is `2`. 623 | 624 | # Characters/Strings 625 | proc gfxPrimitivesSetFont*(fontdata: pointer; cw: uint32; ch: uint32) {.importc.} 626 | ## Sets or resets the current global font data. 627 | ## 628 | ## The font data array is organized in follows: 629 | ## 630 | ## `[fontdata] = [character 0][character 1]...[character 255]` 631 | ## where 632 | ## `[character n] = [byte 1 row 1][byte 2 row 1]...[byte {pitch} row 1] 633 | ## [byte 1 row 2] ...[byte {pitch} row height]` 634 | ## where 635 | ## `[byte n] = [bit 0]...[bit 7]` 636 | ## where 637 | ## `[bit n] = [0 for transparent pixel|1 for colored pixel]` 638 | ## 639 | ## `fontdata` Pointer to array of font data. Set to `nil`, to reset 640 | ## global font to the default `8x8` font. 641 | ## 642 | ## `cw`, `ch` Width and height of character in bytes. 643 | ## Ignored if `fontdata` == `nil`. 644 | 645 | proc gfxPrimitivesSetFontRotation*(rotation: uint32) {.importc.} 646 | ## Sets current global font character rotation steps. 647 | ## 648 | ## Default is `0` (no rotation). 649 | ## 650 | ## `1` = 90deg clockwise. 651 | ## 652 | ## `2` = 180deg clockwise. 653 | ## 654 | ## `3` = 270deg clockwise. 655 | ## 656 | ## Changing the rotation, will reset the character cache. 657 | ## 658 | ## `rotation` Number of 90deg clockwise steps to rotate. 659 | 660 | proc characterColor*(renderer: RendererPtr; x: int16; y: int16; 661 | c: char; color: uint32): SDL_Return {.importc.} 662 | ## Draw a character of the currently set font. 663 | ## 664 | ## `x`, `y` Coordinates of the upper left corner of the character. 665 | ## 666 | ## `c` The character to draw. 667 | 668 | proc characterRGBA*(renderer: RendererPtr; x: int16; y: int16; c: char; 669 | r, g, b, a: uint8): SDL_Return {.importc.} 670 | ## Draw a character of the currently set font. 671 | ## 672 | ## `x`, `y` Coordinates of the upper left corner of the character. 673 | ## 674 | ## `c` The character to draw. 675 | 676 | proc stringColor*(renderer: RendererPtr; x: int16; y: int16; 677 | s: cstring; color: uint32): SDL_Return {.importc.} 678 | ## Draw a string in the currently set font. 679 | ## 680 | ## `x`, `y` Coordinates of the upper left corner of the string. 681 | ## 682 | ## `s` The string to draw. 683 | 684 | proc stringRGBA*(renderer: RendererPtr; x: int16; y: int16; s: cstring; 685 | r, g, b, a: uint8): SDL_Return {.importc, discardable.} 686 | ## Draw a string in the currently set font. 687 | ## 688 | ## `x`, `y` Coordinates of the upper left corner of the string. 689 | ## 690 | ## `s` The string to draw. 691 | 692 | # Ends C function definitions when using C++ 693 | 694 | proc rotozoomSurface*(src: SurfacePtr; angle, zoom: cdouble; 695 | smooth: cint): SurfacePtr {.importc.} 696 | ## Rotates and zooms a surface and optional anti-aliasing. 697 | ## 698 | ## Rotates and zoomes a 32-bit or 8-bit `src` surface to newly created 699 | ## `dst` surface. If the surface is not 8-bit or 32-bit RGBA/ABGR, 700 | ## it will be converted into a 32-bit RGBA format on the fly. 701 | ## 702 | ## `angle` The angle to rotate in degrees. 703 | ## 704 | ## `zoom` The scaling factor. 705 | ## 706 | ## `smooth` Antialiasing flag. Set to `SMOOTHING_ON` to enable. 707 | ## 708 | ## `Return` the new rotozoomed surface. 709 | 710 | proc rotozoomSurfaceXY*(src: SurfacePtr; angle, zoomX, zoomY: cdouble; 711 | smooth: cint): SurfacePtr {.importc.} 712 | ## Rotates and zooms a surface with different horizontal and vertical 713 | ## scaling factors and optional anti-aliasing. 714 | ## 715 | ## Rotates and zooms a 32-bit or 8-bit `src` surface to newly created 716 | ## `dst` surface. If the surface is not 8-bit or 32-bit RGBA/ABGR, 717 | ## it will be converted into a 32-bit RGBA format on the fly. 718 | ## 719 | ## `angle` The angle to rotate in degrees. 720 | ## 721 | ## `zoomx` The horizontal scaling factor. 722 | ## 723 | ## `zoomy` The vertical scaling factor. 724 | ## 725 | ## `smooth` Antialiasing flag. Set to `SMOOTHING_ON` to enable. 726 | ## 727 | ## `Return` the new rotozoomed surface. 728 | 729 | proc rotozoomSurfaceSize*(width, height: cint; angle, zoom: cdouble; 730 | dstwidth, dstheight: var cint) {.importc.} 731 | ## `Return` the size of the resulting target surface 732 | ## for a `rotozoomSurface()` call. 733 | ## 734 | ## `width` The source surface width. 735 | ## 736 | ## `height` The source surface height. 737 | ## 738 | ## `angle` The angle to rotate in degrees. 739 | ## 740 | ## `zoom` The scaling factor. 741 | ## 742 | ## `dstwidth` The calculated width of the rotozoomed destination surface. 743 | ## 744 | ## `dstheight` The calculated height of the rotozoomed destination surface. 745 | 746 | proc rotozoomSurfaceSizeXY*(width, height: cint; angle, zoomX, zoomY: cdouble; 747 | dstwidth, dstheight: var cint) {.importc.} 748 | ## `Return` the size of the resulting target surface 749 | ## for a `rotozoomSurfaceXY()` call. 750 | ## 751 | ## `width` The source surface width. 752 | ## 753 | ## `height` The source surface height. 754 | ## 755 | ## `angle` The angle to rotate in degrees. 756 | ## 757 | ## `zoomx` The horizontal scaling factor. 758 | ## 759 | ## `zoomy` The vertical scaling factor. 760 | ## 761 | ## `dstwidth` The calculated width of the rotozoomed destination surface. 762 | ## 763 | ## `dstheight` The calculated height of the rotozoomed destination surface. 764 | 765 | proc zoomSurface*(src: SurfacePtr; zoomX, zoomY: cdouble; 766 | smooth: cint): SurfacePtr {.importc.} 767 | ## Zoom a surface by independent horizontal and vertical factors 768 | ## with optional smoothing. 769 | ## 770 | ## `zoomx` The horizontal zoom factor. 771 | ## 772 | ## `zoomy` The vertical zoom factor. 773 | ## 774 | ## `smooth` Antialiasing flag. Set to `SMOOTHING_ON` to enable. 775 | ## 776 | ## `Return` the new, zoomed surface. 777 | 778 | proc zoomSurfaceSize*(width, height: cint; zoomX, zoomY: cdouble; 779 | dstWidth, dstHeight: var cint) {.importc.} 780 | ## Calculates the size of the target surface for a `zoomSurface()` call. 781 | ## 782 | ## The minimum size of the target surface is `1`. 783 | ## The input facors can be positive or negative. 784 | ## 785 | ## `width` The width of the soruce surface to zoom. 786 | ## 787 | ## `height` The height of the source surface to zoom. 788 | ## 789 | ## `zoomx` The horizontal zoom factor. 790 | ## 791 | ## `zoomy` The vertical zoom factor. 792 | ## 793 | ## `dstwidth` Pointer to an integer to store the calculated width 794 | ## of the zoomed target surface. 795 | ## 796 | ## `dstheight` Pointer to an integer to store the calculated height 797 | ## of the zoomed target surface. 798 | 799 | 800 | proc shrinkSurface*(src: SurfacePtr; factorx, factorY: cint): SurfacePtr {.importc.} 801 | ## Shrink a surface by an integer ratio using averaging. 802 | ## 803 | ## `factorx` The horizontal shrinking ratio. 804 | ## 805 | ## `factory` The vertical shrinking ratio. 806 | ## 807 | ## `Return` the new, shrunken surface. 808 | 809 | proc rotateSurface90Degrees*(src: SurfacePtr; 810 | numClockwiseTurns: cint): SurfacePtr {.importc.} 811 | ## Rotates a 32 bit surface in increments of 90 degrees. 812 | ## 813 | ## Specialized `90` degree rotator which rotates a `src` surface 814 | ## in `90` degree increments clockwise returning a new surface. 815 | ## Faster than rotozoomer since no scanning or interpolation takes place. 816 | ## 817 | ## Input surface must be 8/16/24/32-bit. 818 | ## 819 | ## (code contributed by J. Schiller, improved by C. Allport and A. Schiffler) 820 | ## 821 | ## `numClockwiseTurns` Number of clockwise `90` degree turns to apply 822 | ## to the source. 823 | ## 824 | ## `Return` the new, rotated surface, 825 | ## or `nil` for surfaces with incorrect input format. 826 | 827 | 828 | proc init*(manager: var FpsManager) {.importc: "SDL_initFramerate".} 829 | ## Initialize the framerate manager, set default framerate 830 | ## of 30Hz and reset delay interpolation. 831 | 832 | proc setFramerate*(manager: var FpsManager; rate: cint): SDL_Return {. 833 | importc: "SDL_setFramerate", discardable.} 834 | ## Set the framerate in Hz. 835 | ## 836 | ## Sets a new framerate for the manager and reset delay interpolation. 837 | ## Rate values must be between `FPS_LOWER_LIMIT` and `FPS_UPPER_LIMIT` 838 | ## inclusive to be accepted. 839 | ## 840 | ## `Return` `0` or value for sucess and `-1` for error. 841 | 842 | proc getFramerate*(manager: var FpsManager): cint {.importc: "SDL_getFramerate".} 843 | ## `Return` the current target framerate in Hz or `-1` on error. 844 | 845 | proc getFramecount*(manager: var FpsManager): cint {.importc: "SDL_getFramecount".} 846 | ## Get the current framecount from the framerate manager. 847 | ## A frame is counted each time `framerateDelay()` is called. 848 | ## 849 | ## `Return` current frame count or `-1` on error. 850 | 851 | proc delay*(manager: var FpsManager): cint {. 852 | importc: "SDL_framerateDelay", discardable.} 853 | ## Generate a delay to accomodate currently set framerate. 854 | ## Call once in the graphics/rendering loop. 855 | ## If the computer cannot keep up with the rate (i.e. drawing too slow), 856 | ## the delay is zero and the delay interpolation is reset. 857 | ## 858 | ## `Return` time that passed since the last call to the procedure in ms. 859 | ## May return `0`. 860 | 861 | 862 | when not defined(SDL_Static): 863 | {.pop.} 864 | 865 | from strutils import splitLines 866 | proc mlStringRGBA*(renderer: RendererPtr; x,y: int16, S: string, R,G,B,A: uint8, lineSpacing = 2'i16) = 867 | ## Draw a multi-line string 868 | var ln = 0 869 | for L in splitLines(S): 870 | renderer.stringRGBA(x,(y + int16(ln * 8) + int16(ln * lineSpacing)),cstring L, R,G,B,A) 871 | inc ln 872 | proc mlStringRGBA*(renderer: RendererPtr; x,y: int16; S: seq[string]; R,G,B,A: uint8; lineSpacing = 2'i16) = 873 | var ln = 0 874 | while ln < S.len: 875 | renderer.stringRGBA(x, y + int16(ln * 8 + ln * lineSpacing), cstring S[ln], R,G,B,A) 876 | inc ln 877 | 878 | {.deprecated: [TFPSmanager: FpsManager].} 879 | -------------------------------------------------------------------------------- /src/sdl2/haptic.nim: -------------------------------------------------------------------------------- 1 | # Simple DirectMedia Layer 2 | # Copyright (C) 1997-2014 Sam Lantinga 3 | # 4 | # This software is provided 'as-is', without any express or implied 5 | # warranty. In no event will the authors be held liable for any damages 6 | # arising from the use of this software. 7 | # 8 | # Permission is granted to anyone to use this software for any purpose, 9 | # including commercial applications, and to alter it and redistribute it 10 | # freely, subject to the following restrictions: 11 | # 12 | # 1. The origin of this software must not be misrepresented; you must not 13 | # claim that you wrote the original software. If you use this software 14 | # in a product, an acknowledgment in the product documentation would be 15 | # appreciated but is not required. 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 3. This notice may not be removed or altered from any source distribution. 19 | # 20 | 21 | ## The SDL haptic subsystem allows you to control 22 | ## haptic (force feedback) devices. 23 | ## 24 | ## The basic usage is as follows: 25 | ## * Initialize the Subsystem (`sdl2.INIT_HAPTIC`). 26 | ## * Open a haptic Device. 27 | ## - `hapticOpen proc<#hapticOpen,cint>`_ to open from index. 28 | ## - `hapticOpenFromJoystick proc<#hapticOpenFromJoystick,JoystickPtr>`_ to open from an existing joystick. 29 | ## * Create an effect (`HapticEffect type<#HapticEffect>`_). 30 | ## * Upload the effect with `newEffect proc<#newEffect,HapticPtr,ptr.HapticEffect>`_. 31 | ## * Run the effect with `runEffect proc<#runEffect,HapticPtr,cint,uint32>`_. 32 | ## * (optional) Free the effect with `destroyEffect proc<#destroyEffect,HapticPtr,cint>`_. 33 | ## * Close the haptic device with `close proc<#close,HapticPtr>`_. 34 | 35 | import "../sdl2" 36 | import "joystick" 37 | 38 | 39 | type 40 | Haptic* = object 41 | ## The haptic object used to identify an SDL haptic. 42 | ## 43 | ## **See also:** 44 | ## * `hapticOpen proc<#hapticOpen,cint>`_ 45 | ## * `hapticOpenFromJoystick proc<#hapticOpenFromJoystick,JoystickPtr>`_ 46 | ## * `close proc<#close,HapticPtr>`_ 47 | 48 | HapticPtr* = ptr Haptic 49 | 50 | 51 | const SDL_HAPTIC_CONSTANT* = (1 shl 0) 52 | ## Constant haptic effect. 53 | ## 54 | ## **See also:** 55 | ## * `HapticCondition type<#HapticCondition>`_ 56 | 57 | const SDL_HAPTIC_SINE* = (1 shl 1) 58 | ## Sine wave effect supported. 59 | ## 60 | ## Periodic haptic effect that simulates sine waves. 61 | ## 62 | ## **See also:** 63 | ## * `HapticPeriodic type<#HapticPeriodic>`_ 64 | 65 | const SDL_HAPTIC_LEFTRIGHT* = (1 shl 2) 66 | ## Left/Right effect supported. 67 | ## 68 | ## Haptic effect for direct control over high/low frequency motors. 69 | ## 70 | ## **See also:** 71 | ## * `HapticLeftRight type<#HapticLeftRight>`_ 72 | ## 73 | ## `Warning:` this value was `SDL_HAPTIC_SQUARE` right before 2.0.0 shipped. 74 | ## Sorry, we ran out of bits, and this is important for XInput devices. 75 | 76 | 77 | # !!! FIXME: put this back when we have more bits in 2.1 78 | # const SDL_HAPTIC_SQUARE* = (1 shl 2) 79 | 80 | 81 | const SDL_HAPTIC_TRIANGLE* = (1 shl 3) 82 | ## Triangle wave effect supported. 83 | ## 84 | ## Periodic haptic effect that simulates triangular waves. 85 | ## 86 | ## **See also:** 87 | ## * `HapticPeriodic type<#HapticPeriodic>`_ 88 | 89 | const SDL_HAPTIC_SAWTOOTHUP* = (1 shl 4) 90 | ## Sawtoothup wave effect supported. 91 | ## 92 | ## Periodic haptic effect that simulates saw tooth up waves. 93 | ## 94 | ## **See also:** 95 | ## * `HapticPeriodic type<#HapticPeriodic>`_ 96 | 97 | const SDL_HAPTIC_SAWTOOTHDOWN* = (1 shl 5) 98 | ## Sawtoothdown wave effect supported. 99 | ## 100 | ## Periodic haptic effect that simulates saw tooth down waves. 101 | ## 102 | ## **See also:** 103 | ## * `HapticPeriodic type<#HapticPeriodic>`_ 104 | 105 | const SDL_HAPTIC_RAMP* = (1 shl 6) 106 | ## Ramp effect supported. 107 | ## 108 | ## Ramp haptic effect. 109 | ## 110 | ## **See also:** 111 | ## * `HapticRamp type<#HapticRamp>`_ 112 | 113 | const SDL_HAPTIC_SPRING* = (1 shl 7) 114 | ## Spring effect supported - uses axes position. 115 | ## 116 | ## Condition haptic effect that simulates a spring. 117 | ## Effect is based on the axes position. 118 | ## 119 | ## **See also:** 120 | ## * `HapticCondition type<#HapticCondition>`_ 121 | 122 | const SDL_HAPTIC_DAMPER* = (1 shl 8) 123 | ## Damper effect supported - uses axes velocity. 124 | ## 125 | ## Condition haptic effect that simulates dampening. 126 | ## Effect is based on the axes velocity. 127 | ## 128 | ## **See also:** 129 | ## * `HapticCondition type<#HapticCondition>`_ 130 | 131 | const SDL_HAPTIC_INERTIA* = (1 shl 9) 132 | ## Inertia effect supported - uses axes acceleration. 133 | ## 134 | ## Condition haptic effect that simulates inertia. 135 | ## Effect is based on the axes acceleration. 136 | ## 137 | ## **See also:** 138 | ## * `HapticCondition type<#HapticCondition>`_ 139 | 140 | const SDL_HAPTIC_FRICTION* = (1 shl 10) 141 | ## Friction effect supported - uses axes movement. 142 | ## 143 | ## Condition haptic effect that simulates friction. 144 | ## Effect is based on the axes movement. 145 | ## 146 | ## **See also:** 147 | ## * `HapticCondition type<#HapticCondition>`_ 148 | 149 | const SDL_HAPTIC_CUSTOM* = (1 shl 11) 150 | ## Custom effect is supported. 151 | ## 152 | ## User defined custom haptic effect. 153 | 154 | const SDL_HAPTIC_GAIN* = (1 shl 12) 155 | ## Device supports setting the global gain. 156 | ## 157 | ## **See also:** 158 | ## * `setGain proc<#setGain,HapticPtr,int>`_ 159 | 160 | const SDL_HAPTIC_AUTOCENTER* = (1 shl 13) 161 | ## Device supports setting autocenter. 162 | ## 163 | ## **See also:** 164 | ## * `setAutoCenter proc<#setAutoCenter,HapticPtr,int>`_ 165 | 166 | const SDL_HAPTIC_STATUS* = (1 shl 14) 167 | ## Device supports querying effect status. 168 | ## 169 | ## **See also:** 170 | ## * `getEffectStatus proc<#getEffectStatus,HapticPtr,cint>`_ 171 | 172 | const SDL_HAPTIC_PAUSE* = (1 shl 15) 173 | ## Devices supports being paused. 174 | ## 175 | ## **See also:** 176 | ## * `pause proc<#pause,HapticPtr>`_ 177 | ## * `unpause proc<#unpause,HapticPtr>`_ 178 | 179 | const SDL_HAPTIC_POLAR* = 0 180 | ## Uses polar coordinates for the direction. 181 | ## 182 | ## **See also:** 183 | ## * `HapticDirection type<#HapticDirection>`_ 184 | 185 | const SDL_HAPTIC_CARTESIAN* = 1 186 | ## Uses cartesian coordinates for the direction. 187 | ## 188 | ## **See also:** 189 | ## * `HapticDirection type<#HapticDirection>`_ 190 | 191 | const SDL_HAPTIC_SPHERICAL* = 2 192 | ## Uses spherical coordinates for the direction. 193 | ## 194 | ## **See also:** 195 | ## * `HapticDirection type<#HapticDirection>`_ 196 | 197 | const SDL_HAPTIC_INFINITY* = 4294967295'u 198 | ## Used to play a device an infinite number of times. 199 | ## 200 | ## **See also:** 201 | ## * `runEffect proc<#runEffect,HapticPtr,cint,uint32>`_ 202 | 203 | 204 | type 205 | HapticDirection* = object 206 | ## Object that represents a haptic direction. 207 | ## 208 | ## This is the direction where the force comes from, 209 | ## instead of the direction in which the force is exerted. 210 | ## 211 | ## Directions can be specified by: 212 | ## * `SDL_HAPTIC_POLAR` : Specified by polar coordinates. 213 | ## * `SDL_HAPTIC_CARTESIAN` : Specified by cartesian coordinates. 214 | ## * `SDL_HAPTIC_SPHERICAL` : Specified by spherical coordinates. 215 | ## 216 | ## Cardinal directions of the haptic device 217 | ## are relative to the positioning of the device. 218 | ## North is considered to be away from the user. 219 | ## 220 | ## If type is `SDL_HAPTIC_POLAR`, direction is encoded by hundredths of a 221 | ## degree starting north and turning clockwise. 222 | ## `SDL_HAPTIC_POLAR` only uses the first `dir` parameter. 223 | ## 224 | ## The cardinal directions would be: 225 | ## * North: `0` (0 degrees) 226 | ## * East: `9000` (90 degrees) 227 | ## * South: `18000` (180 degrees) 228 | ## * West: `27000` (270 degrees) 229 | ## 230 | ## If type is `SDL_HAPTIC_CARTESIAN`, direction is encoded by three positions 231 | ## (X axis, Y axis and Z axis (with 3 axes)). 232 | ## `SDL_HAPTIC_CARTESIAN` uses the first three `dir` parameters. 233 | ## 234 | ## The cardinal directions would be: 235 | ## * North: `0,-1, 0` 236 | ## * East: `1, 0, 0` 237 | ## * South: `0, 1, 0` 238 | ## * West: `-1, 0, 0` 239 | ## 240 | ## The Z axis represents the height of the effect if supported, otherwise 241 | ## it's unused. In cartesian encoding (1, 2) would be the same as (2, 4), 242 | ## you can use any multiple you want, only the direction matters. 243 | ## 244 | ## If type is `SDL_HAPTIC_SPHERICAL`, direction is encoded by two rotations. 245 | ## The first two `dir` parameters are used. 246 | ## 247 | ## The `dir` parameters are as follows 248 | ## (all values are in hundredths of degrees): 249 | ## * Degrees from (`1, 0`) rotated towards (`0, 1`). 250 | ## * Degrees towards (`0, 0, 1`) (device needs at least 3 axes). 251 | ## 252 | ## Example of force coming from the south with all encodings 253 | ## (force coming from the south means the user will have to pull 254 | ## the stick to counteract): 255 | ## 256 | ## .. code-block:: nim 257 | ## var direction: HapticDirection 258 | ## # Cartesian directions 259 | ## direction.type = SDL_HAPTIC_CARTESIAN 260 | ## direction.dir[0] = 0 # X position 261 | ## direction.dir[1] = 1 # Y position 262 | ## # Assuming the device has 2 axes, 263 | ## # we don't need to specify third parameter. 264 | ## # Polar directions 265 | ## direction.type = SDL_HAPTIC_POLAR 266 | ## direction.dir[0] = 18000 # Polar only uses first parameter 267 | ## # Spherical coordinates 268 | ## direction.type = SDL_HAPTIC_SPHERICAL # Spherical encoding 269 | ## direction.dir[0] = 9000 270 | ## # Since we only have two axes we don't need more parameters. 271 | ## 272 | ## The following diagram represents the cardinal directions: 273 | ## :: 274 | ##   .--. 275 | ## |__| .-------. 276 | ## |=.| |.-----.| 277 | ## |--| || || 278 | ## | | |'-----'| 279 | ## |__|~')_____(' 280 | ## [ COMPUTER ] 281 | ## 282 | ## 283 | ## North (0,-1) 284 | ## ^ 285 | ## | 286 | ## | 287 | ## (-1,0) West <----[ HAPTIC ]----> East (1,0) 288 | ## | 289 | ## | 290 | ## v 291 | ## South (0,1) 292 | ## 293 | ## 294 | ## [ USER ] 295 | ## \|||/ 296 | ## (o o) 297 | ## ---ooO-(_)-Ooo--- 298 | ## 299 | ## **See also:** 300 | ## * `SDL_HAPTIC_POLAR const<#SDL_HAPTIC_POLAR>`_ 301 | ## * `SDL_HAPTIC_CARTESIAN const<#SDL_HAPTIC_CARTESIAN>`_ 302 | ## * `SDL_HAPTIC_SPHERICAL const<#SDL_HAPTIC_SPHERICAL>`_ 303 | ## * `HapticEffect type<#HapticEffect>`_ 304 | ## * `numAxes proc<#numAxes,HapticPtr>`_ 305 | kind: uint8 ## The type of encoding. 306 | dir: array[3, int32] ## The encoded direction. 307 | 308 | 309 | type 310 | HapticConstant* = object 311 | ## An object containing a template for a Constant effect. 312 | ## 313 | ## The object is exclusively to the `HAPTIC_CONSTANT` effect. 314 | ## 315 | ## A constant effect applies a constant force 316 | ## in the specified direction to the joystick. 317 | ## 318 | ## **See also:** 319 | ## * `SDL_HAPTIC_CONSTANT const<#SDL_HAPTIC_CONSTANT>`_ 320 | ## * `HapticEffect type<#HapticEffect>`_ 321 | # Header 322 | kind: uint16 ## SDL_HAPTIC_CONSTANT 323 | direction: HapticDirection ## Direction of the effect. 324 | 325 | # Replay 326 | length: uint32 ## Duration of the effect. 327 | delay: uint16 ## Delay before starting the effect. 328 | 329 | # Trigger 330 | button: uint16 ## Button that triggers the effect. 331 | interval: uint16 ## How soon it can be triggered again after button. 332 | 333 | # Constant 334 | level: int16 ## Strength of the constant effect. 335 | 336 | # Envelope 337 | attack_length: uint16 ## Duration of the attack. 338 | attack_level: uint16 ## Level at the start of the attack. 339 | fade_length: uint16 ## Duration of the fade. 340 | fade_level: uint16 ## Level at the end of the fade. 341 | 342 | type 343 | HapticPeriodic* = object 344 | ## An object containing a template for a Periodic effect. 345 | ## 346 | ## The object handles the following effects: 347 | ## * `HAPTIC_SINE` 348 | ## * `HAPTIC_LEFTRIGHT` 349 | ## * `HAPTIC_TRIANGLE` 350 | ## * `HAPTIC_SAWTOOTHUP` 351 | ## * `HAPTIC_SAWTOOTHDOWN` 352 | ## 353 | ## A periodic effect consists in a wave-shaped effect that repeats itself 354 | ## over time. The type determines the shape of the wave and the parameters 355 | ## determine the dimensions of the wave. 356 | ## 357 | ## Phase is given by hundredth of a degree meaning that giving the phase 358 | ## a value of `9000` will displace it 25% of its period. 359 | ## 360 | ## Here are sample values: 361 | ## * `0`: No phase displacement. 362 | ## * `9000`: Displaced 25% of its period. 363 | ## * `18000`: Displaced 50% of its period. 364 | ## * `27000`: Displaced 75% of its period. 365 | ## * `36000`: Displaced 100% of its period, \ 366 | ## same as `0`, but `0` is preferred. 367 | ## 368 | ## Examples: 369 | ## :: 370 | ## SDL_HAPTIC_SINE 371 | ## __ __ __ __ 372 | ## / \ / \ / \ / 373 | ## / \__/ \__/ \__/ 374 | ## 375 | ## SDL_HAPTIC_SQUARE 376 | ## __ __ __ __ __ 377 | ## | | | | | | | | | | 378 | ## | |__| |__| |__| |__| | 379 | ## 380 | ## SDL_HAPTIC_TRIANGLE 381 | ## /\ /\ /\ /\ /\ 382 | ## / \ / \ / \ / \ / 383 | ## / \/ \/ \/ \/ 384 | ## 385 | ## SDL_HAPTIC_SAWTOOTHUP 386 | ## /| /| /| /| /| /| /| 387 | ## / | / | / | / | / | / | / | 388 | ## / |/ |/ |/ |/ |/ |/ | 389 | ## 390 | ## SDL_HAPTIC_SAWTOOTHDOWN 391 | ## \ |\ |\ |\ |\ |\ |\ | 392 | ## \ | \ | \ | \ | \ | \ | \ | 393 | ## \| \| \| \| \| \| \| 394 | ## 395 | ## **See also:** 396 | ## * `SDL_HAPTIC_SINE const<#SDL_HAPTIC_SINE>`_ 397 | ## * `SDL_HAPTIC_LEFTRIGHT const<#SDL_HAPTIC_LEFTRIGHT>`_ 398 | ## * `SDL_HAPTIC_TRIANGLE const<#SDL_HAPTIC_TRIANGLE>`_ 399 | ## * `SDL_HAPTIC_SAWTOOTHDOWN const<#SDL_HAPTIC_SAWTOOTHDOWN>`_ 400 | ## * `SDL_HAPTIC_SAWTOOTHUP const<#SDL_HAPTIC_SAWTOOTHUP>`_ 401 | ## * `HapticEffect type<#HapticEffect>`_ 402 | # Header 403 | kind: uint16 ## SDL_HAPTIC_SINE, SDL_HAPTIC_LEFTRIGHT, 404 | ## SDL_HAPTIC_TRIANGLE, SDL_HAPTIC_SAWTOOTHUP or 405 | ## SDL_HAPTIC_SAWTOOTHDOWN 406 | direction: HapticDirection ## Direction of the effect. 407 | 408 | # Replay 409 | length: uint32 ## Duration of the effect. 410 | delay: uint16 ## Delay before starting the effect. 411 | 412 | # Trigger 413 | button: uint16 ## Button that triggers the effect. 414 | interval: uint16 ## How soon it can be triggered again after button. 415 | 416 | # Periodic 417 | period: uint16 ## Period of the wave. 418 | magnitude: int16 ## Peak value. 419 | offset: int16 ## Mean value of the wave. 420 | phase: uint16 ## Horizontal shift given by hundredth of a cycle. 421 | 422 | # Envelope 423 | attack_length: uint16 ## Duration of the attack. 424 | attack_level: uint16 ## Level at the start of the attack. 425 | fade_length: uint16 ## Duration of the fade. 426 | fade_level: uint16 ## Level at the end of the fade. 427 | 428 | type 429 | HapticCondition* = object 430 | ## An object containing a template for a Condition effect. 431 | ## 432 | ## The object handles the following effects: 433 | ## * `HAPTIC_SPRING`: Effect based on axes position. 434 | ## * `HAPTIC_DAMPER`: Effect based on axes velocity. 435 | ## * `HAPTIC_INERTIA`: Effect based on axes acceleration. 436 | ## * `HAPTIC_FRICTION`: Effect based on axes movement. 437 | ## 438 | ## Direction is handled by condition internals 439 | ## instead of a direction member. 440 | ## 441 | ## The condition effect specific members have three parameters. The first 442 | ## refers to the X axis, the second refers to the Y axis and the third 443 | ## refers to the Z axis. The right terms refer to the positive side 444 | ## of the axis and the left terms refer to the negative side of the axis. 445 | ## 446 | ## Please refer to the `HapticDirection` diagram for which side is 447 | ## positive and which is negative. 448 | ## 449 | ## **See also:** 450 | ## * `HapticDirection type<#HapticDirection>`_ 451 | ## * `SDL_HAPTIC_SPRING const<#SDL_HAPTIC_SPRING>`_ 452 | ## * `SDL_HAPTIC_DAMPER const<#SDL_HAPTIC_DAMPER>`_ 453 | ## * `SDL_HAPTIC_INERTIA const<#SDL_HAPTIC_INERTIA>`_ 454 | ## * `SDL_HAPTIC_FRICTION const<#SDL_HAPTIC_FRICTION>`_ 455 | ## * `HapticEffect type<#HapticEffect>`_ 456 | # Header 457 | kind: uint16 ## SDL_HAPTIC_SPRING, SDL_HAPTIC_DAMPER, 458 | ## SDL_HAPTIC_INERTIA or SDL_HAPTIC_FRICTION 459 | direction: HapticDirection ## Direction of the effect - Not used ATM. 460 | 461 | # Replay 462 | length: uint32 ## Duration of the effect. 463 | delay: uint16 ## Delay before starting the effect. 464 | 465 | # Trigger 466 | button: uint16 ## Button that triggers the effect. 467 | interval: uint16 ## How soon it can be triggered again after button. 468 | 469 | # Condition 470 | right_sat: array[3, uint16] ## Level when joystick is to the positive side. 471 | left_sat: array[3, uint16] ## Level when joystick is to the negative side. 472 | right_coeff: array[3, int16] ## How fast to increase the force towards the positive side. 473 | left_coeff: array[3, int16] ## How fast to increase the force towards the negative side. 474 | deadband: array[3, uint16] ## Size of the dead zone. 475 | center: array[3, int16] ## Position of the dead zone. 476 | 477 | type 478 | HapticRamp* = object 479 | ## An object containing a template for a Ramp effect. 480 | ## 481 | ## This object is exclusively for the `HAPTIC_RAMP` effect. 482 | ## 483 | ## The ramp effect starts at start strength and ends at end strength. 484 | ## It augments in linear fashion. If you use attack and fade with a ramp 485 | ## the effects get added to the ramp effect making the effect become 486 | ## quadratic instead of linear. 487 | ## 488 | ## **See also:** 489 | ## * `SDL_HAPTIC_RAMP const<#SDL_HAPTIC_RAMP>`_ 490 | ## * `HapticEffect type<#HapticEffect>`_ 491 | # Header 492 | kind: uint16 ## SDL_HAPTIC_RAMP 493 | direction: HapticDirection ## Direction of the effect. 494 | 495 | # Replay 496 | length: uint32 ## Duration of the effect. 497 | delay: uint16 ## Delay before starting the effect. 498 | 499 | # Trigger 500 | button: uint16 ## Button that triggers the effect. 501 | interval: uint16 ## How soon it can be triggered again after button. 502 | 503 | # Ramp 504 | start: int16 ## Beginning strength level. 505 | fin: int16 ## Ending strength level. 506 | 507 | # Envelope 508 | attack_length: uint16 ## Duration of the attack. 509 | attack_level: uint16 ## Level at the start of the attack. 510 | fade_length: uint16 ## Duration of the fade. 511 | fade_level: uint16 ## Level at the end of the fade. 512 | 513 | type 514 | HapticLeftRight* = object 515 | ## An object containing a template for a Left/Right effect. 516 | ## 517 | ## This object is exclusively for the `HAPTIC_LEFTRIGHT` effect. 518 | ## 519 | ## The Left/Right effect is used to explicitly control the large and small 520 | ## motors, commonly found in modern game controllers. 521 | ## The small (right) motor is high frequency, 522 | ## and the large (left) motor is low frequency. 523 | ## 524 | ## **See also:** 525 | ## * `SDL_HAPTIC_LEFTRIGHT const<#SDL_HAPTIC_LEFTRIGHT>`_ 526 | ## * `HapticEffect type<#HapticEffect>`_ 527 | # Header 528 | kind: uint16 ## SDL_HAPTIC_LEFTRIGHT 529 | 530 | # Replay 531 | length: uint32 ## Duration of the effect. 532 | 533 | # Rumble 534 | large_magnitude: uint16 ## Control of the large controller motor. 535 | small_magnitude: uint16 ## Control of the small controller motor. 536 | 537 | 538 | type 539 | HapticCustom* = object 540 | ## An object containing a template for the `HAPTIC_CUSTOM` effect. 541 | ## 542 | ## This object is exclusively for the `HAPTIC_CUSTOM` effect. 543 | ## 544 | ## A custom force feedback effect is much like a periodic effect, where 545 | ## the application can define its exact shape. You will have to allocate 546 | ## the data yourself. 547 | ## Data should consist of channels * samples `uint16` samples. 548 | ## 549 | ## If channels is one, the effect is rotated using the defined direction. 550 | ## Otherwise it uses the samples in data for the different axes. 551 | ## 552 | ## **See also:** 553 | ## * `SDL_HAPTIC_CUSTOM const<#SDL_HAPTIC_CUSTOM>`_ 554 | ## * `HapticEffect type<#HapticEffect>`_ 555 | # Header 556 | kind: uint16 ## SDL_HAPTIC_CUSTOM 557 | direction: HapticDirection ## Direction of the effect. 558 | 559 | # Replay 560 | length: uint32 ## Duration of the effect. 561 | delay: uint16 ## Delay before starting the effect. 562 | 563 | # Trigger 564 | button: uint16 ## Button that triggers the effect. 565 | interval: uint16 ## How soon it can be triggered again after button. 566 | 567 | # Custom 568 | channels: uint8 ## Axes to use, minimum of one. 569 | period: uint16 ## Sample periods. 570 | samples: uint16 ## Amount of samples. 571 | data: ptr uint16 ## Should contain `channels*samples` items. 572 | 573 | # Envelope 574 | attack_length: uint16 ## Duration of the attack. 575 | attack_level: uint16 ## Level at the start of the attack. 576 | fade_length: uint16 ## Duration of the fade. 577 | fade_level: uint16 ## Level at the end of the fade. 578 | 579 | type 580 | HapticEffect* {.union.} = object 581 | ## The generic template for any haptic effect. 582 | ## 583 | ## All values max at `32767` (`0x7FFF`). 584 | ## Signed values also can be negative. 585 | ## Time values unless specified otherwise are in milliseconds. 586 | ## 587 | ## You can also pass `HAPTIC_INFINITY` to length instead of a `0`-`32767` 588 | ## value. Neither delay, interval, attack_length nor fade_length support 589 | ## `HAPTIC_INFINITY`. Fade will also not be used since effect never ends. 590 | ## 591 | ## Additionally, the `HAPTIC_RAMP` effect does not support a duration of 592 | ## `HAPTIC_INFINITY`. 593 | ## 594 | ## Button triggers may not be supported on all devices, it is advised to 595 | ## not use them if possible. Buttons start at index `1` instead of index 596 | ## `0` like the joystick. 597 | ## 598 | ## If both `attack_length` and `fade_level` are `0`, 599 | ## the envelope is not used, otherwise both values are used. 600 | ## 601 | ## Common parts: 602 | ## 603 | ## .. code-block:: nim 604 | ## # Replay - All effects have this 605 | ## length: uint32 # Duration of effect (ms). 606 | ## delay: uint16 # Delay before starting effect. 607 | ## # Trigger - All effects have this 608 | ## button: uint16 # Button that triggers effect. 609 | ## interval: uint16 # How soon before effect can be triggered again. 610 | ## # Envelope - All effects except condition effects have this 611 | ## attack_length: uint16 # Duration of the attack (ms). 612 | ## attack_level: uint16 # Level at the start of the attack. 613 | ## fade_length: uint16 # Duration of the fade out (ms). 614 | ## fade_level: uint16 # Level at the end of the fade. 615 | ## 616 | ## Here we have an example of a constant effect evolution in time: 617 | ## :: 618 | ## Strength 619 | ## ^ 620 | ## | 621 | ## | effect level --> _________________ 622 | ## | / \ 623 | ## | / \ 624 | ## | / \ 625 | ## | / \ 626 | ## | attack_level --> | \ 627 | ## | | | <--- fade_level 628 | ## | 629 | ## +--------------------------------------------------> Time 630 | ## [--] [---] 631 | ## attack_length fade_length 632 | ## 633 | ## [------------------][-----------------------] 634 | ## delay length 635 | ## 636 | ## Note either the attack_level or the fade_level may be above the actual 637 | ## effect level. 638 | ## 639 | ## **See also:** 640 | ## * `HapticConstant type<#HapticConstant>`_ 641 | ## * `HapticPeriodic type<#HapticPeriodic>`_ 642 | ## * `HapticCondition type<#HapticCondition>`_ 643 | ## * `HapticRamp type<#HapticRamp>`_ 644 | ## * `HapticLeftRight type<#HapticLeftRight>`_ 645 | ## * `HapticCustom type<#HapticCustom>`_ 646 | # Common for all force feedback effects 647 | kind: uint16 ## Effect type. 648 | constant: HapticConstant ## Constant effect. 649 | periodic: HapticPeriodic ## Periodic effect. 650 | condition: HapticCondition ## Condition effect. 651 | ramp: HapticRamp ## Ramp effect. 652 | leftright: HapticLeftRight ## Left/Right effect. 653 | custom: HapticCustom ## Custom effect. 654 | 655 | 656 | when defined(SDL_Static): 657 | static: echo "SDL_Static option is deprecated and will soon be removed. Instead please use --dynlibOverride:SDL2." 658 | else: 659 | {.push callConv: cdecl, dynlib: LibName.} 660 | 661 | proc numHaptics*(): cint {.importc: "SDL_NumHaptics".} 662 | ## Count the number of haptic devices attached to the system. 663 | ## 664 | ## `Return` number of haptic devices detected on the system. 665 | 666 | proc hapticName*(device_index: cint): cstring {.importc: "SDL_HapticName".} 667 | ## Get the implementation dependent name of a haptic device. 668 | ## 669 | ## This can be called before any joysticks are opened. 670 | ## If no name can be found, this procedure returns `nil`. 671 | ## 672 | ## `device_index` Index of the device to get its name. 673 | ## 674 | ## `Return` name of the device or `nil` on error. 675 | ## 676 | ## **See also:** 677 | ## * `numHaptics proc<#numHaptics>`_ 678 | 679 | proc hapticOpen*(device_index: cint): HapticPtr {.importc: "SDL_HapticOpen".} 680 | ## Opens a haptic device for usage. 681 | ## 682 | ## The index passed as an argument refers to the N'th haptic device 683 | ## on this system. 684 | ## 685 | ## When opening a haptic device, its gain will be set to maximum and 686 | ## autocenter will be disabled. To modify these values use 687 | ## `hapticSetGain()` and `hapticSetAutocenter()`. 688 | ## 689 | ## `device_index` Index of the device to open. 690 | ## 691 | ## `Return` device identifier or `nil` on error. 692 | ## 693 | ## **See also:** 694 | ## * `index proc<#index,HapticPtr>`_ 695 | ## * `hapticOpenFromMouse proc<#hapticOpenFromMouse>`_ 696 | ## * `hapticOpenFromJoystick proc<#hapticOpenFromJoystick,JoystickPtr>`_ 697 | ## * `close proc<#close,HapticPtr>`_ 698 | ## * `setGain proc<#setGain,HapticPtr,int>`_ 699 | ## * `setAutocenter proc<#setAutocenter,HapticPtr,int>`_ 700 | ## * `pause proc<#pause,HapticPtr>`_ 701 | ## * `stopAll proc<#stopAll,HapticPtr>`_ 702 | 703 | proc hapticOpened*(device_index: cint): cint {.importc: "SDL_HapticOpened".} 704 | ## Checks if the haptic device at index has been opened. 705 | ## 706 | ## `device_index` Index to check to see if it has been opened. 707 | ## 708 | ## `Return` `1` if it has been opened or `0` if it hasn't. 709 | ## 710 | ## **See also:** 711 | ## * `hapticOpen proc<#hapticOpen,cint>`_ 712 | ## * `index proc<#index,HapticPtr>`_ 713 | 714 | proc index*(haptic: HapticPtr): cint {.importc: "SDL_HapticIndex".} 715 | ## Gets the index of a haptic device. 716 | ## 717 | ## `haptic` Haptic device to get the index of. 718 | ## 719 | ## `Return` The index of the haptic device or `-1` on error. 720 | ## 721 | ## **See also:** 722 | ## * `hapticOpen proc<#hapticOpen,cint>`_ 723 | ## * `hapticOpened proc<#hapticOpened,cint>`_ 724 | 725 | proc mouseIsHaptic*(): cint {.importc: "SDL_MouseIsHaptic".} 726 | ## Gets whether or not the current mouse has haptic capabilities. 727 | ## 728 | ## `Return` `1` if the mouse is haptic, `0` if it isn't. 729 | ## 730 | ## **See also:** 731 | ## * `hapticOpenFromMouse proc<#hapticOpenFromMouse>`_ 732 | 733 | proc hapticOpenFromMouse*(): HapticPtr {.importc: "SDL_HapticOpenFromMouse".} 734 | ## Tries to open a haptic device from the current mouse. 735 | ## 736 | ## `Return` The haptic device identifier or `nil` on error. 737 | ## 738 | ## **See also:** 739 | ## * `mouseIsHaptic proc<#mouseIsHaptic>`_ 740 | ## * `hapticOpen proc<#hapticOpen,cint>`_ 741 | 742 | proc joystickIsHaptic*(joystick: Joystick): cint {.importc: "SDL_JoystickIsHaptic".} 743 | ## Checks to see if a joystick has haptic features. 744 | ## 745 | ## `joystick` Joystick to test for haptic capabilities. 746 | ## 747 | ## `Return` `1` if the joystick is haptic, `0` if it isn't 748 | ## or `-1` if an error ocurred. 749 | ## 750 | ## **See also:** 751 | ## * `hapticOpenFromJoystick proc<#hapticOpenFromJoystick,JoystickPtr>`_ 752 | 753 | proc hapticOpenFromJoystick*(joystick: JoystickPtr): HapticPtr {. 754 | importc: "SDL_HapticOpenFromJoystick".} 755 | ## Opens a haptic device for usage from a joystick device. 756 | ## 757 | ## You must still close the haptic device separately. 758 | ## It will not be closed with the joystick. 759 | ## 760 | ## When opening from a joystick you should first close the haptic device 761 | ## before closing the joystick device. If not, on some implementations the 762 | ## haptic device will also get unallocated and you'll be unable to use 763 | ## force feedback on that device. 764 | ## 765 | ## `joystick` Joystick to create a haptic device from. 766 | ## 767 | ## `Return` A valid haptic device identifier on success or `nil` on error. 768 | ## 769 | ## **See also:** 770 | ## * `hapticOpen proc<#hapticOpen,cint>`_ 771 | ## * `close proc<#close,HapticPtr>`_ 772 | 773 | proc close*(haptic: HapticPtr) {.importc: "SDL_HapticClose".} 774 | ## Closes a haptic device previously opened with `hapticOpen proc<#hapticOpen,cint>`_. 775 | ## 776 | ## `haptic` Haptic device to close. 777 | 778 | proc numEffects*(haptic: HapticPtr):cint {.importc: "SDL_HapticNumEffects".} 779 | ## Returns the number of effects a haptic device can store. 780 | ## 781 | ## On some platforms this isn't fully supported, and therefore is an 782 | ## approximation. Always check to see if your created effect was actually 783 | ## created and do not rely solely on `hapticNumEffects()`. 784 | ## 785 | ## `haptic` The haptic device to query effect max. 786 | ## 787 | ## `Return` The number of effects the haptic device can store 788 | ## or `-1` on error. 789 | ## 790 | ## **See also:** 791 | ## * `numEffectsPlaying proc<#numEffectsPlaying,HapticPtr>`_ 792 | ## * `query proc<#query,HapticPtr>`_ 793 | 794 | proc numEffectsPlaying*(haptic: HapticPtr): cint {. 795 | importc: "SDL_HapticNumEffectsPlaying".} 796 | ## Returns the number of effects a haptic device can play at the same time. 797 | ## 798 | ## This is not supported on all platforms, but will always return a value. 799 | ## Added here for the sake of completeness. 800 | ## 801 | ## `haptic` The haptic device to query maximum playing effects. 802 | ## 803 | ## `Return` The number of effects the haptic device can play 804 | ## at the same time or `-1` on error. 805 | ## 806 | ## **See also:** 807 | ## * `numEffects proc<#numEffects,HapticPtr>`_ 808 | ## * `query proc<#query,HapticPtr>`_ 809 | 810 | proc query*(haptic: HapticPtr): uint {.importc: "SDL_HapticQuery".} 811 | ## Gets the haptic device's supported features in bitwise manner. 812 | ## 813 | ## Example: 814 | ## 815 | ## .. code-block:: nim 816 | ## if hapticQuery(haptic) and HAPTIC_CONSTANT: 817 | ## echo("We have constant haptic effect!") 818 | ## 819 | ## `haptic` The haptic device to query. 820 | ## 821 | ## `Return` Haptic features in bitwise manner (OR'd). 822 | ## 823 | ## **See also:** 824 | ## * `numEffects proc<#numEffects,HapticPtr>`_ 825 | ## * `effectSupported proc<#effectSupported,HapticPtr,ptr.HapticEffect>`_ 826 | 827 | proc numAxes*(haptic: HapticPtr):cint {.importc: "SDL_HapticNumAxes".} 828 | ## Gets the number of haptic axes the device has. 829 | ## 830 | ## **See also:** 831 | ## * `HapticDirection type<#HapticDirection>`_ 832 | 833 | proc effectSupported*(haptic: HapticPtr, effect: ptr HapticEffect): cint {. 834 | importc: "SDL_HapticEffectSupported".} 835 | ## Checks to see if effect is supported by haptic. 836 | ## 837 | ## `haptic` Haptic device to check on. 838 | ## 839 | ## `effect` Effect to check to see if it is supported. 840 | ## 841 | ## `Return` `1` if effect is supported, `0` if it isn't 842 | ## or `-1` on error. 843 | ## 844 | ## **See also:** 845 | ## * `query proc<#query,HapticPtr>`_ 846 | ## * `newEffect proc<#newEffect,HapticPtr,ptr.HapticEffect>`_ 847 | 848 | proc newEffect*(haptic: HapticPtr, effect: ptr HapticEffect): cint {. 849 | importc: "SDL_HapticNewEffect".} 850 | ## Creates a new haptic effect on the device. 851 | ## 852 | ## `haptic` Haptic device to create the effect on. 853 | ## 854 | ## `effect` Properties of the effect to create. 855 | ## 856 | ## `Return` The identifier of the effect on success or `-1` on error. 857 | ## 858 | ## **See also:** 859 | ## * `updateEffect proc<#updateEffect,HapticPtr,cint,ptr.HapticEffect>`_ 860 | ## * `runEffect proc<#runEffect,HapticPtr,cint,uint32>`_ 861 | ## * `destroyEffect proc<#destroyEffect,HapticPtr,cint>`_ 862 | 863 | proc updateEffect*(haptic: HapticPtr, effect: cint, 864 | data: ptr HapticEffect): cint {.importc: "SDL_HapticUpdateEffect".} 865 | ## Updates the properties of an effect. 866 | ## 867 | ## Can be used dynamically, although behavior when dynamically changing 868 | ## direction may be strange. Specifically the effect may reupload itself 869 | ## and start playing from the start. You cannot change the type either 870 | ## when running `hapticUpdateEffect()`. 871 | ## 872 | ## `haptic` Haptic device that has the effect. 873 | ## 874 | ## `effect` Identifier of the effect to update. 875 | ## 876 | ## `data` New effect properties to use. 877 | ## 878 | ## `Return` `0` on success or `-1` on error. 879 | ## 880 | ## **See also:** 881 | ## * `newEffect proc<#newEffect,HapticPtr,ptr.HapticEffect>`_ 882 | ## * `runEffect proc<#runEffect,HapticPtr,cint,uint32>`_ 883 | ## * `destroyEffect proc<#destroyEffect,HapticPtr,cint>`_ 884 | 885 | proc runEffect*(haptic: HapticPtr, effect: cint, 886 | iterations: uint32): cint {.importc: "SDL_HapticRunEffect".} 887 | ## Runs the haptic effect on its associated haptic device. 888 | ## 889 | ## If iterations are `HAPTIC_INFINITY`, it'll run the effect over and over 890 | ## repeating the envelope (attack and fade) every time. 891 | ## If you only want the effect to last forever, set `HAPTIC_INFINITY` 892 | ## in the effect's length parameter. 893 | ## 894 | ## `haptic` Haptic device to run the effect on. 895 | ## 896 | ## `effect` Identifier of the haptic effect to run. 897 | ## 898 | ## `iterations` Number of iterations to run the effect. 899 | ## Use `HAPTIC_INFINITY` for infinity. 900 | ## 901 | ## `Return` `0` on success or `-1` on error. 902 | ## 903 | ## **See also:** 904 | ## * `stopEffect proc<#stopEffect,HapticPtr,cint>`_ 905 | ## * `destroyEffect proc<#destroyEffect,HapticPtr,cint>`_ 906 | ## * `getEffectStatus proc<#getEffectStatus,HapticPtr,cint>`_ 907 | 908 | proc stopEffect*(haptic: HapticPtr, 909 | effect: cint): cint {.importc: "SDL_HapticStopEffect".} 910 | ## Stops the haptic effect on its associated haptic device. 911 | ## 912 | ## `haptic` Haptic device to stop the effect on. 913 | ## 914 | ## `effect` Identifier of the effect to stop. 915 | ## 916 | ## `Return` `0` on success or `-1` on error. 917 | ## 918 | ## **See also:** 919 | ## * `runEffect proc<#runEffect,HapticPtr,cint,uint32>`_ 920 | ## * `destroyEffect proc<#destroyEffect,HapticPtr,cint>`_ 921 | 922 | proc destroyEffect*(haptic: HapticPtr, 923 | effect: cint) {.importc: "SDL_HapticDestroyEffect".} 924 | ## Destroys a haptic effect on the device. 925 | ## 926 | ## This will stop the effect if it's running. Effects are automatically 927 | ## destroyed when the device is closed. 928 | ## 929 | ## `haptic` Device to destroy the effect on. 930 | ## 931 | ## `effect` Identifier of the effect to destroy. 932 | ## 933 | ## **See also:** 934 | ## * `newEffect proc<#newEffect,HapticPtr,ptr.HapticEffect>`_ 935 | 936 | proc getEffectStatus*(haptic: HapticPtr, effect: cint): cint {. 937 | importc: "SDL_HapticGetEffectStatus".} 938 | ## Gets the status of the current effect on the haptic device. 939 | ## 940 | ## Device must support the `HAPTIC_STATUS` feature. 941 | ## 942 | ## `haptic` Haptic device to query the effect status on. 943 | ## 944 | ## `effect` Identifier of the effect to query its status. 945 | ## 946 | ## `Return` `0` if it isn't playing, `1` if it is playing 947 | ## or `-1` on error. 948 | ## 949 | ## **See also:** 950 | ## * `runEffect proc<#runEffect,HapticPtr,cint,uint32>`_ 951 | ## * `stopEffect proc<#stopEffect,HapticPtr,cint>`_ 952 | 953 | proc setGain*(haptic: HapticPtr, 954 | gain: int): cint {.importc: "SDL_HapticSetGain".} 955 | ## Sets the global gain of the device. 956 | ## 957 | ## Device must support the `HAPTIC_GAIN` feature. 958 | ## 959 | ## The user may specify the maximum gain by setting the environment variable 960 | ## `HAPTIC_GAIN_MAX` which should be between `0` and `100`. All calls to 961 | ## `hapticSetGain()` will scale linearly using `HAPTIC_GAIN_MAX` as the 962 | ## maximum. 963 | ## 964 | ## `haptic` Haptic device to set the gain on. 965 | ## 966 | ## `gain` Value to set the gain to, should be between `0` and `100`. 967 | ## 968 | ## `Return` `0` on success or `-1` on error. 969 | ## 970 | ## **See also:** 971 | ## * `query proc<#query,HapticPtr>`_ 972 | 973 | proc setAutocenter*(haptic: HapticPtr, autocenter: int): cint {. 974 | importc: "SDL_HapticSetAutocenter".} 975 | ## Sets the global autocenter of the device. 976 | ## 977 | ## Autocenter should be between `0` and `100`. 978 | ## Setting it to `0` will disable autocentering. 979 | ## 980 | ## Device must support the `HAPTIC_AUTOCENTER` feature. 981 | ## 982 | ## `haptic` Haptic device to set autocentering on. 983 | ## 984 | ## `autocenter` Value to set autocenter to, `0` disables autocentering. 985 | ## 986 | ## `Return` `0` on success or `-1` on error. 987 | ## 988 | ## **See also:** 989 | ## * `query proc<#query,HapticPtr>`_ 990 | 991 | proc pause*(haptic: HapticPtr): cint {.importc: "SDL_HapticPause".} 992 | ## Pauses a haptic device. 993 | ## 994 | ## Device must support the `HAPTIC_PAUSE` feature. 995 | ## Call `unpause()` to resume playback. 996 | ## 997 | ## Do not modify the effects nor add new ones while the device is paused. 998 | ## That can cause all sorts of weird errors. 999 | ## 1000 | ## `haptic` Haptic device to pause. 1001 | ## 1002 | ## `Return` `0` on success or `-1` on error. 1003 | ## 1004 | ## **See also:** 1005 | ## * `unpause proc<#unpause,HapticPtr>`_ 1006 | 1007 | proc unpause*(haptic: HapticPtr): cint {.importc: "SDL_HapticUnpause".} 1008 | ## Unpauses a haptic device. 1009 | ## 1010 | ## Call to unpause after `pause()`. 1011 | ## 1012 | ## `haptic` Haptic device to unpause. 1013 | ## 1014 | ## `Return` `0` on success or `-1` on error. 1015 | ## 1016 | ## **See also:** 1017 | ## * `pause proc<#pause,HapticPtr>`_ 1018 | 1019 | proc stopAll*(haptic: HapticPtr): cint {.importc: "SDL_HapticStopAll".} 1020 | ## Stops all the currently playing effects on a haptic device. 1021 | ## 1022 | ## `haptic` Haptic device to stop. 1023 | ## 1024 | ## `Return` `0` on success or `-1` on error. 1025 | 1026 | proc rumbleSupported*(haptic: HapticPtr): cint {. 1027 | importc: "SDL_HapticRumbleSupported".} 1028 | ## Checks to see if rumble is supported on a haptic device. 1029 | ## 1030 | ## `haptic` Haptic device to check to see if it supports rumble. 1031 | ## 1032 | ## `Return` `1` if effect is supported, `0` if it isn't 1033 | ## or `-1` on error. 1034 | ## 1035 | ## **See also:** 1036 | ## * `rumbleInit proc<#rumbleInit,HapticPtr>`_ 1037 | ## * `rumblePlay proc<#rumblePlay,HapticPtr,float,uint32>`_ 1038 | ## * `rumbleStop proc<#rumbleStop,HapticPtr>`_ 1039 | 1040 | proc rumbleInit*(haptic: HapticPtr): cint {.importc: "SDL_HapticRumbleInit".} 1041 | ## Initializes the haptic device for simple rumble playback. 1042 | ## 1043 | ## `haptic` Haptic device to initialize for simple rumble playback. 1044 | ## 1045 | ## `Return` `0` on success or `-1` on error. 1046 | ## 1047 | ## **See also:** 1048 | ## * `hapticOpen proc<#hapticOpen,cint>`_ 1049 | ## * `rumbleSupported proc<#rumbleSupported,HapticPtr>`_ 1050 | ## * `rumblePlay proc<#rumblePlay,HapticPtr,float,uint32>`_ 1051 | ## * `rumbleStop proc<#rumbleStop,HapticPtr>`_ 1052 | 1053 | proc rumblePlay*(haptic: HapticPtr, strength: float, length: uint32): cint {. 1054 | importc: "SDL_HapticRumblePlay".} 1055 | ## Runs simple rumble on a haptic device 1056 | ## 1057 | ## `haptic` Haptic device to play rumble effect on. 1058 | ## 1059 | ## `strength` Strength of the rumble to play as a `0`-`1` float value. 1060 | ## 1061 | ## `length` Length of the rumble to play in milliseconds. 1062 | ## 1063 | ## `Return` `0` on success or `-1` on error. 1064 | ## 1065 | ## **See also:** 1066 | ## * `rumbleSupported proc<#rumbleSupported,HapticPtr>`_ 1067 | ## * `rumbleInit proc<#rumbleInit,HapticPtr>`_ 1068 | ## * `rumbleStop proc<#rumbleStop,HapticPtr>`_ 1069 | 1070 | proc rumbleStop*(haptic: HapticPtr):cint {.importc: "SDL_HapticRumbleStop".} 1071 | ## Stops the simple rumble on a haptic device. 1072 | ## 1073 | ## `haptic` Haptic to stop the rumble on. 1074 | ## 1075 | ## `Return` `0` on success or `-1` on error. 1076 | ## 1077 | ## **See also:** 1078 | ## * `rumbleSupported proc<#rumbleSupported,HapticPtr>`_ 1079 | ## * `rumbleInit proc<#rumbleInit,HapticPtr>`_ 1080 | ## * `rumbleStop proc<#rumbleStop,HapticPtr>`_ 1081 | 1082 | 1083 | when not defined(SDL_Static): 1084 | {.pop.} 1085 | -------------------------------------------------------------------------------- /src/sdl2/image.nim: -------------------------------------------------------------------------------- 1 | ## A simple library to load images of various formats as SDL surfaces. 2 | 3 | 4 | import sdl2 5 | 6 | when not defined(SDL_Static): 7 | when defined(windows): 8 | const LibName = "SDL2_image.dll" 9 | elif defined(macosx): 10 | const LibName = "libSDL2_image.dylib" 11 | else: 12 | const LibName = "libSDL2_image(|-2.0).so(|.0)" 13 | else: 14 | static: echo "SDL_Static option is deprecated and will soon be removed. Instead please use --dynlibOverride:SDL2." 15 | 16 | const 17 | IMG_INIT_JPG* = 0x00000001 18 | IMG_INIT_PNG* = 0x00000002 19 | IMG_INIT_TIF* = 0x00000004 20 | IMG_INIT_WEBP* = 0x00000008 21 | 22 | when not defined(SDL_Static): 23 | {.push callConv: cdecl, dynlib: LibName.} 24 | 25 | proc linkedVersion*(): ptr SDL_version {.importc: "IMG_Linked_Version".} 26 | ## Gets the version of the dynamically linked image library. 27 | 28 | proc init*(flags: cint = IMG_INIT_JPG or IMG_INIT_PNG): cint {.importc: "IMG_Init".} 29 | ## It returns the flags successfully initialized, or 0 on failure. 30 | ## This is completely different than sdl2.init() -_- 31 | 32 | proc quit*() {.importc: "IMG_Quit".} 33 | ## Unloads libraries loaded with `init()`. 34 | 35 | proc loadTyped_RW*(src: RWopsPtr; freesrc: cint; 36 | `type`: cstring): SurfacePtr {.importc: "IMG_LoadTyped_RW".} 37 | ## Load an image from an SDL data source. 38 | ## 39 | ## `kind` may be one of: `"BMP"`, `"GIF"`, `"PNG"`, etc. 40 | ## 41 | ## If the image format supports a transparent pixel, SDL will set the 42 | ## colorkey for the surface. You can enable RLE acceleration on the 43 | ## surface afterwards by calling: 44 | ## 45 | ## .. code-block:: nim 46 | ## setColorKey(image, SDL_RLEACCEL, image.format.colorkey) 47 | 48 | # Convenience functions 49 | proc load*(file: cstring): SurfacePtr {.importc: "IMG_Load".} 50 | proc load_RW*(src: RWopsPtr; 51 | freesrc: cint): SurfacePtr {.importc: "IMG_Load_RW".} 52 | proc load*(src: RWopsPtr; freesrc: cint): SurfacePtr {.importc: "IMG_Load_RW".} 53 | ## Load an image directly into a render texture. 54 | 55 | proc loadTexture*(renderer: RendererPtr; 56 | file: cstring): TexturePtr {.importc: "IMG_LoadTexture".} 57 | proc loadTexture_RW*(renderer: RendererPtr; src: RWopsPtr; 58 | freesrc: cint): TexturePtr {. 59 | importc: "IMG_LoadTexture_RW".} 60 | proc loadTexture*(renderer: RendererPtr; src: RWopsPtr; 61 | freesrc: cint): TexturePtr {. 62 | importc: "IMG_LoadTexture_RW".} 63 | proc loadTextureTyped_RW*(renderer: RendererPtr; 64 | src: RWopsPtr; 65 | freesrc: cint; 66 | `type`: cstring): TexturePtr {. 67 | importc: "IMG_LoadTextureTyped_RW".} 68 | proc loadTexture*(renderer: RendererPtr; 69 | src: RWopsPtr; 70 | freesrc: cint; 71 | `type`: cstring): TexturePtr {. 72 | importc: "IMG_LoadTextureTyped_RW".} 73 | 74 | # Functions to detect a file type, given a seekable source 75 | proc isICO*(src: RWopsPtr): cint {.importc: "IMG_isICO".} 76 | proc isCUR*(src: RWopsPtr): cint {.importc: "IMG_isCUR".} 77 | proc isBMP*(src: RWopsPtr): cint {.importc: "IMG_isBMP".} 78 | proc isGIF*(src: RWopsPtr): cint {.importc: "IMG_isGIF".} 79 | proc isJPG*(src: RWopsPtr): cint {.importc: "IMG_isJPG".} 80 | proc isLBM*(src: RWopsPtr): cint {.importc: "IMG_isLBM".} 81 | proc isPCX*(src: RWopsPtr): cint {.importc: "IMG_isPCX".} 82 | proc isPNG*(src: RWopsPtr): cint {.importc: "IMG_isPNG".} 83 | proc isPNM*(src: RWopsPtr): cint {.importc: "IMG_isPNM".} 84 | proc isTIF*(src: RWopsPtr): cint {.importc: "IMG_isTIF".} 85 | proc isXCF*(src: RWopsPtr): cint {.importc: "IMG_isXCF".} 86 | proc isXPM*(src: RWopsPtr): cint {.importc: "IMG_isXPM".} 87 | proc isXV*(src: RWopsPtr): cint {.importc: "IMG_isXV".} 88 | proc isWEBP*(src: RWopsPtr): cint {.importc: "IMG_isWEBP".} 89 | # Individual loading functions 90 | proc loadICO_RW*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadICO_RW".} 91 | proc loadICO*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadICO_RW".} 92 | proc loadCUR_RW*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadCUR_RW".} 93 | proc loadCUR*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadCUR_RW".} 94 | proc loadBMP_RW*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadBMP_RW".} 95 | proc loadBMP*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadBMP_RW".} 96 | proc loadGIF_RW*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadGIF_RW".} 97 | proc loadGIF*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadGIF_RW".} 98 | proc loadJPG_RW*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadJPG_RW".} 99 | proc loadJPG*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadJPG_RW".} 100 | proc loadLBM_RW*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadLBM_RW".} 101 | proc loadLBM*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadLBM_RW".} 102 | proc loadPCX_RW*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadPCX_RW".} 103 | proc loadPCX*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadPCX_RW".} 104 | proc loadPNG_RW*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadPNG_RW".} 105 | proc loadPNG*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadPNG_RW".} 106 | proc loadPNM_RW*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadPNM_RW".} 107 | proc loadPNM*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadPNM_RW".} 108 | proc loadTGA_RW*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadTGA_RW".} 109 | proc loadTGA*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadTGA_RW".} 110 | proc loadTIF_RW*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadTIF_RW".} 111 | proc loadTIF*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadTIF_RW".} 112 | proc loadXCF_RW*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadXCF_RW".} 113 | proc loadXCF*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadXCF_RW".} 114 | proc loadXPM_RW*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadXPM_RW".} 115 | proc loadXPM*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadXPM_RW".} 116 | proc loadXV_RW*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadXV_RW".} 117 | proc loadXV(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadXV_RW".} 118 | proc loadWEBP_RW*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadWEBP_RW".} 119 | proc loadWEBP*(src: RWopsPtr): SurfacePtr {.importc: "IMG_LoadWEBP_RW".} 120 | proc readXPMFromArray*(xpm: cstringArray): SurfacePtr {.importc: "IMG_ReadXPMFromArray".} 121 | proc readXPM*(xpm: cstringArray): SurfacePtr {.importc: "IMG_ReadXPMFromArray".} 122 | # Saving functions 123 | proc savePNG*(surface: SurfacePtr, file: cstring): cint {.importc: "IMG_SavePNG".} 124 | 125 | when not defined(SDL_Static): 126 | {.pop.} 127 | -------------------------------------------------------------------------------- /src/sdl2/joystick.nim: -------------------------------------------------------------------------------- 1 | discard """ Simple DirectMedia Layer 2 | Copyright (C) 1997-2014 Sam Lantinga 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | 20 | """ 21 | 22 | ## Include file for SDL joystick event handling 23 | ## 24 | ## The term "device_index" identifies currently plugged in joystick devices 25 | ## between 0 and SDL_NumJoysticks, with the exact joystick behind a 26 | ## device_index changing as joysticks are plugged and unplugged. 27 | ## 28 | ## The term "instance_id" is the current instantiation of a joystick device in 29 | ## the system, if the joystick is removed and then re-inserted then it will get 30 | ## a new instance_id, instance_id's are monotonically increasing identifiers of 31 | ## a joystick plugged in. 32 | ## 33 | ## The term JoystickGUID is a stable 128-bit identifier for a joystick device 34 | ## that does not change over time, it identifies class of the device 35 | ## (a X360 wired controller for example). This identifier is platform dependent. 36 | ## 37 | ## In order to use these functions, `init()` must have been called with 38 | ## the `INIT_JOYSTICK` flag. This causes SDL to scan the system for joysticks, 39 | ## and load appropriate drivers. 40 | ## 41 | ## If you would like to receive joystick updates while the application 42 | ## is in the background, you should set the following hint before calling 43 | ## `init()`: `SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS` 44 | import "../sdl2" 45 | 46 | 47 | # The joystick structure used to identify an SDL joystick 48 | type 49 | Joystick* = object 50 | JoystickPtr* = ptr Joystick 51 | 52 | # A structure that encodes the stable unique id for a joystick device# 53 | type 54 | JoystickGuid* = object 55 | data: array[16, uint8] 56 | JoystickID* = int32 57 | ## This is a unique ID for a joystick for the time it is connected to the 58 | ## system, and is never reused for the lifetime of the application. If the 59 | ## joystick is disconnected and reconnected, it will get a new ID. 60 | ## 61 | ## The ID value starts at `0` and increments from there. 62 | ## The value `-1` is an invalid ID. 63 | JoystickType* = enum 64 | SDL_JOYSTICK_TYPE_UNKNOWN, 65 | SDL_JOYSTICK_TYPE_GAMECONTROLLER, 66 | SDL_JOYSTICK_TYPE_WHEEL, 67 | SDL_JOYSTICK_TYPE_ARCADE_STICK, 68 | SDL_JOYSTICK_TYPE_FLIGHT_STICK, 69 | SDL_JOYSTICK_TYPE_DANCE_PAD, 70 | SDL_JOYSTICK_TYPE_GUITAR, 71 | SDL_JOYSTICK_TYPE_DRUM_KIT, 72 | SDL_JOYSTICK_TYPE_ARCADE_PAD, 73 | SDL_JOYSTICK_TYPE_THROTTLE 74 | JoystickPowerLevel* = enum 75 | SDL_JOYSTICK_POWER_UNKNOWN = -1, 76 | SDL_JOYSTICK_POWER_EMPTY, # <= 5% 77 | SDL_JOYSTICK_POWER_LOW, # <= 20% 78 | SDL_JOYSTICK_POWER_MEDIUM, # <= 70% 79 | SDL_JOYSTICK_POWER_FULL, # <= 100% 80 | SDL_JOYSTICK_POWER_WIRED, 81 | SDL_JOYSTICK_POWER_MAX 82 | 83 | const 84 | SDL_IPHONE_MAX_GFORCE*: cfloat = 5.0 85 | 86 | when defined(SDL_Static): 87 | static: echo "SDL_Static option is deprecated and will soon be removed. Instead please use --dynlibOverride:SDL2." 88 | else: 89 | {.push callConv: cdecl, dynlib: LibName.} 90 | 91 | 92 | proc numJoysticks*(): cint {.importc: "SDL_NumJoysticks".} 93 | ## Count the number of joysticks attached to the system right now. 94 | 95 | proc joystickNameForIndex*(device_index: cint): cstring {. 96 | importc: "SDL_JoystickNameForIndex".} 97 | ## Get the implementation dependent name of a joystick. 98 | ## 99 | ## This can be called before any joysticks are opened. 100 | ## If no name can be found, this procedure returns `nil`. 101 | 102 | proc joystickOpen*(device_index: cint): JoystickPtr {. 103 | importc: "SDL_JoystickOpen".} 104 | ## Open a joystick for use. 105 | ## 106 | ## The index passed as an argument refers to the N'th joystick on the system. 107 | ## This index is not the value which will identify this joystick in future 108 | ## joystick events. The joystick's instance id (`JoystickID`) will be used 109 | ## there instead. 110 | ## 111 | ## `Return` a joystick identifier, or `nil` if an error occurred. 112 | 113 | proc joystickName*(joystick: JoystickPtr): cstring {.importc: "SDL_JoystickName".} 114 | ## `Return` the name for this currently opened joystick. 115 | ## If no name can be found, this procedure returns `nil`. 116 | 117 | proc name*(joystick: JoystickPtr): cstring {.inline.} = 118 | ## `Return` the name for this currently opened joystick. 119 | ## If no name can be found, this procedure returns `nil`. 120 | joystick.joystickName 121 | 122 | proc joystickGetDeviceGUID*(device_index: cint): JoystickGUID {. 123 | importc: "SDL_JoystickGetDeviceGUID".} 124 | ## Return the GUID for the joystick at this index. 125 | ## 126 | ## This can be called before any joysticks are opened. 127 | 128 | proc joystickGetGUID*(joystick: JoystickPtr): JoystickGUID {. 129 | importc: "SDL_JoystickGetGUID".} 130 | ## `Return` the GUID for this opened joystick. 131 | 132 | proc getGUID*(joystick: JoystickPtr): JoystickGUID {.inline.} = 133 | ## `Return` the GUID for this opened joystick. 134 | joystick.joystickGetGUID 135 | 136 | proc joystickGetGUIDString*(guid: JoystickGUID, pszGUID: cstring, cbGUID: cint) {. 137 | importc: "SDL_JoystickGetGUIDString".} 138 | ## `Return` a string representation for this guid. 139 | ## 140 | ## `pszGUID` must point to at least 33 bytes 141 | ## (32 for the string plus a `nil` terminator). 142 | 143 | proc joystickGetGUIDFromString*(pchGUID: cstring): JoystickGUID {. 144 | importc: "SDL_JoystickGetGUIDFromString".} 145 | ## Convert a string into a joystick GUID. 146 | 147 | proc joystickGetAttached*(joystick: JoystickPtr): Bool32 {. 148 | importc: "SDL_JoystickGetAttached".} 149 | ## `Return` `true` if the joystick has been opened and currently 150 | ## connected, or `false` if it has not. 151 | 152 | proc getAttached*(joystick: JoystickPtr): Bool32 {.inline.} = 153 | ## `Return` `true` if the joystick has been opened and currently 154 | ## connected, or `false` if it has not. 155 | joystick.joystickGetAttached 156 | 157 | proc joystickInstanceID*(joystick: JoystickPtr): JoystickID {. 158 | importc: "SDL_JoystickInstanceID".} 159 | ## Get the instance ID of an opened joystick, 160 | ## or `-1` if the joystick is invalid. 161 | 162 | proc instanceID*(joystick: JoystickPtr): JoystickID {.inline.} = 163 | ## Get the instance ID of an opened joystick, 164 | ## or `-1` if the joystick is invalid. 165 | joystick.joystickInstanceID 166 | 167 | proc joystickNumAxes*(joystick: JoystickPtr): cint {. 168 | importc: "SDL_JoystickNumAxes".} 169 | ## Get the number of general axis controls on a joystick. 170 | 171 | proc numAxes*(joystick: JoystickPtr): cint {.inline.} = 172 | ## Get the number of general axis controls on a joystick. 173 | joystick.joystickNumAxes 174 | 175 | proc joystickNumBalls*(joystick: JoystickPtr): cint {. 176 | importc: "SDL_JoystickNumBalls".} 177 | ## Get the number of trackballs on a joystick. 178 | ## 179 | ## Joystick trackballs have only relative motion events associated 180 | ## with them and their state cannot be polled. 181 | 182 | proc numBalls*(joystick: JoystickPtr): cint {.inline.} = 183 | ## Get the number of trackballs on a joystick. 184 | ## 185 | ## Joystick trackballs have only relative motion events associated 186 | ## with them and their state cannot be polled. 187 | joystick.joystickNumBalls 188 | 189 | proc joystickNumHats*(joystick: JoystickPtr): cint {. 190 | importc: "SDL_JoystickNumHats".} 191 | ## Get the number of POV hats on a joystick. 192 | 193 | proc numHats*(joystick: JoystickPtr): cint {.inline.} = 194 | ## Get the number of POV hats on a joystick. 195 | joystick.joystickNumHats 196 | 197 | proc joystickNumButtons*(joystick: JoystickPtr): cint {. 198 | importc: "SDL_JoystickNumButtons".} 199 | ## Get the number of buttons on a joystick. 200 | 201 | proc numButtons*(joystick: JoystickPtr): cint {.inline.} = 202 | ## Get the number of buttons on a joystick. 203 | joystick.joystickNumButtons 204 | 205 | proc joystickUpdate*() {.importc: "SDL_JoystickUpdate".} 206 | ## Update the current state of the open joysticks. 207 | ## 208 | ## This is called automatically by the event loop if any joystick 209 | ## events are enabled. 210 | 211 | proc joystickEventState*(state: cint): cint {. 212 | importc: "SDL_JoystickEventState".} 213 | ## Enable/disable joystick event polling. 214 | ## 215 | ## If joystick events are disabled, you must call `joystickUpdate()` 216 | ## yourself and check the state of the joystick when you want joystick 217 | ## information. 218 | ## 219 | ## The `state` can be one of `SDL_QUERY`, `SDL_ENABLE` or `SDL_IGNORE`. 220 | 221 | proc joystickGetAxis*(joystick: JoystickPtr, axis: cint): int16 {. 222 | importc: "SDL_JoystickGetAxis".} 223 | ## Get the current state of an axis control on a joystick. 224 | ## 225 | ## The state is a value ranging from `-32768` to `32767`. 226 | ## 227 | ## The axis indices start at index `0`. 228 | 229 | proc getAxis*(joystick: JoystickPtr, axis: cint): int16 {.inline.} = 230 | ## Get the current state of an axis control on a joystick. 231 | ## 232 | ## The state is a value ranging from `-32768` to `32767`. 233 | ## 234 | ## The axis indices start at index `0`. 235 | joystick.joystickGetAxis(axis) 236 | 237 | const 238 | SDL_HAT_CENTERED*: cint = 0x00000000 239 | SDL_HAT_UP*: cint = 0x00000001 240 | SDL_HAT_RIGHT*: cint = 0x00000002 241 | SDL_HAT_DOWN*: cint = 0x00000004 242 | SDL_HAT_LEFT*: cint = 0x00000008 243 | SDL_HAT_RIGHTUP*: cint = SDL_HAT_RIGHT or SDL_HAT_UP 244 | SDL_HAT_RIGHTDOWN*: cint = SDL_HAT_RIGHT or SDL_HAT_DOWN 245 | SDL_HAT_LEFTUP*: cint = SDL_HAT_LEFT or SDL_HAT_UP 246 | SDL_HAT_LEFTDOWN*: cint = SDL_HAT_LEFT or SDL_HAT_DOWN 247 | 248 | 249 | proc joystickGetHat*(joystick: JoystickPtr, hat: cint): uint8 {. 250 | importc: "SDL_JoystickGetHat".} 251 | ## Get the current state of a POV hat on a joystick. 252 | ## 253 | ## The hat indices start at index `0`. 254 | ## 255 | ## `Return` The return value is one of the following positions: 256 | ## * SDL_HAT_CENTERED 257 | ## * SDL_HAT_UP 258 | ## * SDL_HAT_RIGHT 259 | ## * SDL_HAT_DOWN 260 | ## * SDL_HAT_LEFT 261 | ## * SDL_HAT_RIGHTUP 262 | ## * SDL_HAT_RIGHTDOWN 263 | ## * SDL_HAT_LEFTUP 264 | ## * SDL_HAT_LEFTDOWN 265 | 266 | proc getHat*(joystick: JoystickPtr, hat: cint): uint8 {.inline.} = 267 | ## Get the current state of a POV hat on a joystick. 268 | ## 269 | ## The hat indices start at index `0`. 270 | ## 271 | ## `Return` The return value is one of the following positions: 272 | ## * SDL_HAT_CENTERED 273 | ## * SDL_HAT_UP 274 | ## * SDL_HAT_RIGHT 275 | ## * SDL_HAT_DOWN 276 | ## * SDL_HAT_LEFT 277 | ## * SDL_HAT_RIGHTUP 278 | ## * SDL_HAT_RIGHTDOWN 279 | ## * SDL_HAT_LEFTUP 280 | ## * SDL_HAT_LEFTDOWN 281 | joystick.joystickGetHat(hat) 282 | 283 | proc joystickGetBall*(joystick: JoystickPtr, ball: cint, dx: ptr cint, dy: ptr cint): cint {. 284 | importc: "SDL_JoystickGetBall".} 285 | ## Get the ball axis change since the last poll. 286 | ## 287 | ## `Return` `0`, or `-1` if you passed it invalid parameters. 288 | ## 289 | ## The ball indices start at index `0`. 290 | 291 | proc getBall*(joystick: JoystickPtr, ball: cint, dx: ptr cint, dy: ptr cint): cint {.inline.} = 292 | ## Get the ball axis change since the last poll. 293 | ## 294 | ## `Return` `0`, or `-1` if you passed it invalid parameters. 295 | ## 296 | ## The ball indices start at index `0`. 297 | joystick.joystickGetBall(ball, dx, dy) 298 | 299 | proc joystickGetButton*(joystick: JoystickPtr, button: cint): uint8 {. 300 | importc: "SDL_JoystickGetButton".} 301 | ## Get the current state of a button on a joystick. 302 | ## 303 | ## The button indices start at index `0`. 304 | 305 | proc getButton*(joystick: JoystickPtr, button: cint): uint8 {.inline.} = 306 | ## Get the current state of a button on a joystick. 307 | ## 308 | ## The button indices start at index `0`. 309 | joystick.joystickGetButton(button) 310 | 311 | proc joystickRumble*(gamecontroller: JoystickPtr, lowFrequencyRumble, 312 | highFrequencyRUmble: uint16, durationMs: uint32): SDL_Return {. 313 | importc: "SDL_JoystickRumble".} 314 | ## Start a rumble effect. 315 | ## 316 | ## Each call to this function cancels any previous rumble effect, and calling 317 | ## it with 0 intensity stops any rumbling. 318 | ## 319 | ## `Return` 0, or -1 if rumble isn't supported on this joystick 320 | 321 | proc joystickRumbleTriggers*(joystick: JoystickPtr, leftRumble, 322 | rightRumble: uint16, durationMs: uint32): cint {. 323 | importc: "SDL_JoystickRumbleTriggers".} 324 | ## Start a rumble effect in the joystick's triggers 325 | ## 326 | ## Each call to this function cancels any previous trigger rumble effect, and 327 | ## calling it with 0 intensity stops any rumbling. 328 | ## 329 | ## Note that this is rumbling of the _triggers_ and not the game controller as 330 | ## a whole. This is currently only supported on Xbox One controllers. If you 331 | ## want the (more common) whole-controller rumble, use `joystickRumble` 332 | ## instead. 333 | ## 334 | ## `Return` 0, or -1 if trigger rumble isn't supported on this joystick 335 | 336 | proc joystickHasLED*(joystick: JoystickPtr): Bool32 {. 337 | importc: "SDL_JoystickHasLED".} 338 | ## Query whether a joystick has an LED. 339 | ## 340 | ## An example of a joystick LED is the light on the back of a PlayStation 4's 341 | ## DualShock 4 controller. 342 | ## 343 | ## `Return` True32 if the joystick has a modifiable LED, False32 otherwise. 344 | 345 | proc joystickHasRumble*(joystick: JoystickPtr): Bool32 {. 346 | importc: "SDL_JoystickHasRumble".} 347 | ## Query whether a joystick has rumble support. 348 | ## 349 | ## `Return` True32 if the joystick has rumble, False32 otherwise. 350 | 351 | proc joystickHasRumbleTriggers*(joystick: JoystickPtr): Bool32 {. 352 | importc: "SDL_JoystickHasRumbleTriggers".} 353 | ## Query whether a joystick has rumble support on triggers. 354 | ## 355 | ## `Return` True32 if the joystick has trigger rumble, False32 otherwise. 356 | 357 | proc joystickSetLED*(joystick: JoystickPtr, red, green, blue: uint8): cint {. 358 | importc: "SDL_JoystickSetLED".} 359 | ## Update a joystick's LED color. 360 | ## 361 | ## An example of a joystick LED is the light on the back of a PlayStation 4's 362 | ## DualShock 4 controller. 363 | ## 364 | ## `Return` 0 on success, -1 if this joystick does not have a modifiable LED 365 | 366 | proc joystickSendEffect*(joystick: JoystickPtr, data: pointer, 367 | size: cint): cint {.importc: "SDL_JoystickSendEffect".} 368 | ## Send a joystick specific effect packet 369 | ## 370 | ## `Return` 0, or -1 if this joystick or driver doesn't support effect packets 371 | 372 | proc joystickCurrentPowerLevel*(joystick: JoystickPtr): JoystickGuid {. 373 | importc: "SDL_JoystickCurrentPowerLevel".} 374 | ## Get the battery level of a joystick as JoystickPowerLevel. 375 | ## 376 | ## `Return` the current battery level as JoystickPowerLevel on success or 377 | ## `SDL_JOYSTICK_POWER_UNKNOWN` if it is unknown 378 | 379 | proc joystickClose*(joystick: JoystickPtr) {.importc: "SDL_JoystickClose".} 380 | ## Close a joystick previously opened with `joystickOpen()`. 381 | 382 | proc close*(joystick: JoystickPtr) {.inline.} = 383 | ## Close a joystick previously opened with `joystickOpen()`. 384 | joystick.joystickClose() 385 | 386 | when not defined(SDL_Static): 387 | {.pop.} 388 | -------------------------------------------------------------------------------- /src/sdl2/private/keycodes.nim: -------------------------------------------------------------------------------- 1 | # do not import this, it is included in sdl2.nim 2 | 3 | type 4 | Scancode* {.size: sizeof(cint).} = enum 5 | ## The SDL keyboard scancode representation. 6 | ## 7 | ## Values of this type are used to represent keyboard keys, among other 8 | ## places in the ``key.keysym.scancode`` field of the Event structure. 9 | ## 10 | ## The values in this enumeration are based on the USB usage page standard: 11 | ## https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf 12 | 13 | SDL_SCANCODE_UNKNOWN = 0, 14 | SDL_SCANCODE_A = 4, SDL_SCANCODE_B = 5, SDL_SCANCODE_C = 6, 15 | SDL_SCANCODE_D = 7, SDL_SCANCODE_E = 8, SDL_SCANCODE_F = 9, 16 | SDL_SCANCODE_G = 10, SDL_SCANCODE_H = 11, SDL_SCANCODE_I = 12, 17 | SDL_SCANCODE_J = 13, SDL_SCANCODE_K = 14, SDL_SCANCODE_L = 15, 18 | SDL_SCANCODE_M = 16, SDL_SCANCODE_N = 17, SDL_SCANCODE_O = 18, 19 | SDL_SCANCODE_P = 19, SDL_SCANCODE_Q = 20, SDL_SCANCODE_R = 21, 20 | SDL_SCANCODE_S = 22, SDL_SCANCODE_T = 23, SDL_SCANCODE_U = 24, 21 | SDL_SCANCODE_V = 25, SDL_SCANCODE_W = 26, SDL_SCANCODE_X = 27, 22 | SDL_SCANCODE_Y = 28, SDL_SCANCODE_Z = 29, SDL_SCANCODE_1 = 30, 23 | SDL_SCANCODE_2 = 31, SDL_SCANCODE_3 = 32, SDL_SCANCODE_4 = 33, 24 | SDL_SCANCODE_5 = 34, SDL_SCANCODE_6 = 35, SDL_SCANCODE_7 = 36, 25 | SDL_SCANCODE_8 = 37, SDL_SCANCODE_9 = 38, SDL_SCANCODE_0 = 39, 26 | SDL_SCANCODE_RETURN = 40, SDL_SCANCODE_ESCAPE = 41, 27 | SDL_SCANCODE_BACKSPACE = 42, SDL_SCANCODE_TAB = 43, 28 | SDL_SCANCODE_SPACE = 44, SDL_SCANCODE_MINUS = 45, 29 | SDL_SCANCODE_EQUALS = 46, SDL_SCANCODE_LEFTBRACKET = 47, 30 | SDL_SCANCODE_RIGHTBRACKET = 48, SDL_SCANCODE_BACKSLASH = 49, 31 | SDL_SCANCODE_NONUSHASH = 50, # 32 | SDL_SCANCODE_SEMICOLON = 51, SDL_SCANCODE_APOSTROPHE = 52, SDL_SCANCODE_GRAVE = 53, 33 | SDL_SCANCODE_COMMA = 54, SDL_SCANCODE_PERIOD = 55, 34 | SDL_SCANCODE_SLASH = 56, SDL_SCANCODE_CAPSLOCK = 57, SDL_SCANCODE_F1 = 58, 35 | SDL_SCANCODE_F2 = 59, SDL_SCANCODE_F3 = 60, SDL_SCANCODE_F4 = 61, 36 | SDL_SCANCODE_F5 = 62, SDL_SCANCODE_F6 = 63, SDL_SCANCODE_F7 = 64, 37 | SDL_SCANCODE_F8 = 65, SDL_SCANCODE_F9 = 66, SDL_SCANCODE_F10 = 67, 38 | SDL_SCANCODE_F11 = 68, SDL_SCANCODE_F12 = 69, 39 | SDL_SCANCODE_PRINTSCREEN = 70, SDL_SCANCODE_SCROLLLOCK = 71, 40 | SDL_SCANCODE_PAUSE = 72, SDL_SCANCODE_INSERT = 73, 41 | SDL_SCANCODE_HOME = 74, SDL_SCANCODE_PAGEUP = 75, 42 | SDL_SCANCODE_DELETE = 76, SDL_SCANCODE_END = 77, 43 | SDL_SCANCODE_PAGEDOWN = 78, SDL_SCANCODE_RIGHT = 79, 44 | SDL_SCANCODE_LEFT = 80, SDL_SCANCODE_DOWN = 81, SDL_SCANCODE_UP = 82, SDL_SCANCODE_NUMLOCKCLEAR = 83, 45 | SDL_SCANCODE_KP_DIVIDE = 84, SDL_SCANCODE_KP_MULTIPLY = 85, 46 | SDL_SCANCODE_KP_MINUS = 86, SDL_SCANCODE_KP_PLUS = 87, 47 | SDL_SCANCODE_KP_ENTER = 88, SDL_SCANCODE_KP_1 = 89, 48 | SDL_SCANCODE_KP_2 = 90, SDL_SCANCODE_KP_3 = 91, SDL_SCANCODE_KP_4 = 92, 49 | SDL_SCANCODE_KP_5 = 93, SDL_SCANCODE_KP_6 = 94, SDL_SCANCODE_KP_7 = 95, 50 | SDL_SCANCODE_KP_8 = 96, SDL_SCANCODE_KP_9 = 97, SDL_SCANCODE_KP_0 = 98, 51 | SDL_SCANCODE_KP_PERIOD = 99, SDL_SCANCODE_NONUSBACKSLASH = 100, 52 | SDL_SCANCODE_APPLICATION = 101, ## windows contextual menu, compose 53 | SDL_SCANCODE_POWER = 102, 54 | SDL_SCANCODE_KP_EQUALS = 103, SDL_SCANCODE_F13 = 104, 55 | SDL_SCANCODE_F14 = 105, SDL_SCANCODE_F15 = 106, SDL_SCANCODE_F16 = 107, 56 | SDL_SCANCODE_F17 = 108, SDL_SCANCODE_F18 = 109, SDL_SCANCODE_F19 = 110, 57 | SDL_SCANCODE_F20 = 111, SDL_SCANCODE_F21 = 112, SDL_SCANCODE_F22 = 113, 58 | SDL_SCANCODE_F23 = 114, SDL_SCANCODE_F24 = 115, 59 | SDL_SCANCODE_EXECUTE = 116, SDL_SCANCODE_HELP = 117, 60 | SDL_SCANCODE_MENU = 118, SDL_SCANCODE_SELECT = 119, 61 | SDL_SCANCODE_STOP = 120, SDL_SCANCODE_AGAIN = 121, ## redo 62 | SDL_SCANCODE_UNDO = 122, SDL_SCANCODE_CUT = 123, SDL_SCANCODE_COPY = 124, 63 | SDL_SCANCODE_PASTE = 125, SDL_SCANCODE_FIND = 126, 64 | SDL_SCANCODE_MUTE = 127, SDL_SCANCODE_VOLUMEUP = 128, SDL_SCANCODE_VOLUMEDOWN = 129, 65 | SDL_SCANCODE_KP_COMMA = 133, SDL_SCANCODE_KP_EQUALSAS400 = 134, SDL_SCANCODE_INTERNATIONAL1 = 135, 66 | SDL_SCANCODE_INTERNATIONAL2 = 136, SDL_SCANCODE_INTERNATIONAL3 = 137, #*< Yen 67 | SDL_SCANCODE_INTERNATIONAL4 = 138, SDL_SCANCODE_INTERNATIONAL5 = 139, 68 | SDL_SCANCODE_INTERNATIONAL6 = 140, SDL_SCANCODE_INTERNATIONAL7 = 141, 69 | SDL_SCANCODE_INTERNATIONAL8 = 142, SDL_SCANCODE_INTERNATIONAL9 = 143, SDL_SCANCODE_LANG1 = 144, #*< Hangul/English toggle 70 | SDL_SCANCODE_LANG2 = 145, ## Hanja conversion 71 | SDL_SCANCODE_LANG3 = 146, ## Katakana 72 | SDL_SCANCODE_LANG4 = 147, ## Hiragana 73 | SDL_SCANCODE_LANG5 = 148, ## Zenkaku/Hankaku 74 | SDL_SCANCODE_LANG6 = 149, ## reserved 75 | SDL_SCANCODE_LANG7 = 150, ## reserved 76 | SDL_SCANCODE_LANG8 = 151, ## reserved 77 | SDL_SCANCODE_LANG9 = 152, ## reserved 78 | SDL_SCANCODE_ALTERASE = 153, ## Erase-Eaze 79 | SDL_SCANCODE_SYSREQ = 154, SDL_SCANCODE_CANCEL = 155, 80 | SDL_SCANCODE_CLEAR = 156, SDL_SCANCODE_PRIOR = 157, 81 | SDL_SCANCODE_RETURN2 = 158, SDL_SCANCODE_SEPARATOR = 159, 82 | SDL_SCANCODE_OUT = 160, SDL_SCANCODE_OPER = 161, 83 | SDL_SCANCODE_CLEARAGAIN = 162, SDL_SCANCODE_CRSEL = 163, 84 | SDL_SCANCODE_EXSEL = 164, SDL_SCANCODE_KP_00 = 176, 85 | SDL_SCANCODE_KP_000 = 177, SDL_SCANCODE_THOUSANDSSEPARATOR = 178, 86 | SDL_SCANCODE_DECIMALSEPARATOR = 179, SDL_SCANCODE_CURRENCYUNIT = 180, 87 | SDL_SCANCODE_CURRENCYSUBUNIT = 181, SDL_SCANCODE_KP_LEFTPAREN = 182, 88 | SDL_SCANCODE_KP_RIGHTPAREN = 183, SDL_SCANCODE_KP_LEFTBRACE = 184, 89 | SDL_SCANCODE_KP_RIGHTBRACE = 185, SDL_SCANCODE_KP_TAB = 186, 90 | SDL_SCANCODE_KP_BACKSPACE = 187, SDL_SCANCODE_KP_A = 188, 91 | SDL_SCANCODE_KP_B = 189, SDL_SCANCODE_KP_C = 190, SDL_SCANCODE_KP_D = 191, 92 | SDL_SCANCODE_KP_E = 192, SDL_SCANCODE_KP_F = 193, 93 | SDL_SCANCODE_KP_XOR = 194, SDL_SCANCODE_KP_POWER = 195, 94 | SDL_SCANCODE_KP_PERCENT = 196, SDL_SCANCODE_KP_LESS = 197, 95 | SDL_SCANCODE_KP_GREATER = 198, SDL_SCANCODE_KP_AMPERSAND = 199, 96 | SDL_SCANCODE_KP_DBLAMPERSAND = 200, SDL_SCANCODE_KP_VERTICALBAR = 201, 97 | SDL_SCANCODE_KP_DBLVERTICALBAR = 202, SDL_SCANCODE_KP_COLON = 203, 98 | SDL_SCANCODE_KP_HASH = 204, SDL_SCANCODE_KP_SPACE = 205, 99 | SDL_SCANCODE_KP_AT = 206, SDL_SCANCODE_KP_EXCLAM = 207, 100 | SDL_SCANCODE_KP_MEMSTORE = 208, SDL_SCANCODE_KP_MEMRECALL = 209, 101 | SDL_SCANCODE_KP_MEMCLEAR = 210, SDL_SCANCODE_KP_MEMADD = 211, 102 | SDL_SCANCODE_KP_MEMSUBTRACT = 212, SDL_SCANCODE_KP_MEMMULTIPLY = 213, 103 | SDL_SCANCODE_KP_MEMDIVIDE = 214, SDL_SCANCODE_KP_PLUSMINUS = 215, 104 | SDL_SCANCODE_KP_CLEAR = 216, SDL_SCANCODE_KP_CLEARENTRY = 217, 105 | SDL_SCANCODE_KP_BINARY = 218, SDL_SCANCODE_KP_OCTAL = 219, 106 | SDL_SCANCODE_KP_DECIMAL = 220, SDL_SCANCODE_KP_HEXADECIMAL = 221, 107 | SDL_SCANCODE_LCTRL = 224, SDL_SCANCODE_LSHIFT = 225, SDL_SCANCODE_LALT = 226, #*< alt, option 108 | SDL_SCANCODE_LGUI = 227, ## windows, command (apple), meta 109 | SDL_SCANCODE_RCTRL = 228, SDL_SCANCODE_RSHIFT = 229, SDL_SCANCODE_RALT = 230, #*< alt gr, option 110 | SDL_SCANCODE_RGUI = 231, ## windows, command (apple), meta 111 | SDL_SCANCODE_MODE = 257, 112 | SDL_SCANCODE_AUDIONEXT = 258, SDL_SCANCODE_AUDIOPREV = 259, 113 | SDL_SCANCODE_AUDIOSTOP = 260, SDL_SCANCODE_AUDIOPLAY = 261, 114 | SDL_SCANCODE_AUDIOMUTE = 262, SDL_SCANCODE_MEDIASELECT = 263, 115 | SDL_SCANCODE_WWW = 264, SDL_SCANCODE_MAIL = 265, 116 | SDL_SCANCODE_CALCULATOR = 266, SDL_SCANCODE_COMPUTER = 267, 117 | SDL_SCANCODE_AC_SEARCH = 268, SDL_SCANCODE_AC_HOME = 269, 118 | SDL_SCANCODE_AC_BACK = 270, SDL_SCANCODE_AC_FORWARD = 271, 119 | SDL_SCANCODE_AC_STOP = 272, SDL_SCANCODE_AC_REFRESH = 273, SDL_SCANCODE_AC_BOOKMARKS = 274, 120 | SDL_SCANCODE_BRIGHTNESSDOWN = 275, SDL_SCANCODE_BRIGHTNESSUP = 276, SDL_SCANCODE_DISPLAYSWITCH = 277, 121 | SDL_SCANCODE_KBDILLUMTOGGLE = 278, SDL_SCANCODE_KBDILLUMDOWN = 279, 122 | SDL_SCANCODE_KBDILLUMUP = 280, SDL_SCANCODE_EJECT = 281, SDL_SCANCODE_SLEEP = 282, 123 | SDL_NUM_SCANCODES = 512 124 | ## not a key, just marks the number of scancodes for array bounds 125 | 126 | const SDLK_SCANCODE_MASK = 1 shl 30 127 | template SDL_SCANCODE_TO_KEYCODE(some: ScanCode): untyped = (some.cint or SDLK_SCANCODE_MASK) 128 | 129 | const 130 | K_UNKNOWN*: cint = 0 131 | 132 | K_BACKSPACE*: cint = '\b'.cint 133 | K_TAB*: cint = '\t'.cint 134 | K_RETURN*: cint = '\r'.cint 135 | K_ESCAPE*: cint = '\27'.cint 136 | K_SPACE*: cint = ' '.cint 137 | K_EXCLAIM*: cint = '!'.cint 138 | K_QUOTEDBL*: cint = '"'.cint 139 | K_HASH*: cint = '#'.cint 140 | K_DOLLAR*: cint = '$'.cint 141 | K_PERCENT*: cint = '%'.cint 142 | K_AMPERSAND*: cint = '&'.cint 143 | K_QUOTE*: cint = '\''.cint 144 | K_LEFTPAREN*: cint = '('.cint 145 | K_RIGHTPAREN*: cint = ')'.cint 146 | K_ASTERISK*: cint = '*'.cint 147 | K_PLUS*: cint = '+'.cint 148 | K_COMMA*: cint = ','.cint 149 | K_MINUS*: cint = '-'.cint 150 | K_PERIOD*: cint = '.'.cint 151 | K_SLASH*: cint = '/'.cint 152 | K_0*: cint = '0'.cint 153 | K_1*: cint = '1'.cint 154 | K_2*: cint = '2'.cint 155 | K_3*: cint = '3'.cint 156 | K_4*: cint = '4'.cint 157 | K_5*: cint = '5'.cint 158 | K_6*: cint = '6'.cint 159 | K_7*: cint = '7'.cint 160 | K_8*: cint = '8'.cint 161 | K_9*: cint = '9'.cint 162 | K_COLON*: cint = ':'.cint 163 | K_SEMICOLON*: cint = ';'.cint 164 | K_LESS*: cint = '<'.cint 165 | K_EQUALS*: cint = '='.cint 166 | K_GREATER*: cint = '>'.cint 167 | K_QUESTION*: cint = '?'.cint 168 | K_AT*: cint = '@'.cint # Skip uppercase letters 169 | K_LEFTBRACKET*: cint = '['.cint 170 | K_BACKSLASH*: cint = '\\'.cint 171 | K_RIGHTBRACKET*: cint = ']'.cint 172 | K_CARET*: cint = '^'.cint 173 | K_UNDERSCORE*: cint = '_'.cint 174 | K_BACKQUOTE*: cint = '`'.cint 175 | K_a*: cint = 'a'.cint 176 | K_b*: cint = 'b'.cint 177 | K_c*: cint = 'c'.cint 178 | K_d*: cint = 'd'.cint 179 | K_e*: cint = 'e'.cint 180 | K_f*: cint = 'f'.cint 181 | K_g*: cint = 'g'.cint 182 | K_h*: cint = 'h'.cint 183 | K_i*: cint = 'i'.cint 184 | K_j*: cint = 'j'.cint 185 | K_k*: cint = 'k'.cint 186 | K_l*: cint = 'l'.cint 187 | K_m*: cint = 'm'.cint 188 | K_n*: cint = 'n'.cint 189 | K_o*: cint = 'o'.cint 190 | K_p*: cint = 'p'.cint 191 | K_q*: cint = 'q'.cint 192 | K_r*: cint = 'r'.cint 193 | K_s*: cint = 's'.cint 194 | K_t*: cint = 't'.cint 195 | K_u*: cint = 'u'.cint 196 | K_v*: cint = 'v'.cint 197 | K_w*: cint = 'w'.cint 198 | K_x*: cint = 'x'.cint 199 | K_y*: cint = 'y'.cint 200 | K_z*: cint = 'z'.cint 201 | 202 | K_DELETE*: cint = '\127'.cint 203 | K_CAPSLOCK*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CAPSLOCK) 204 | 205 | K_F1*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F1) 206 | K_F2*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F2) 207 | K_F3*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F3) 208 | K_F4*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F4) 209 | K_F5*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F5) 210 | K_F6*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F6) 211 | K_F7*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F7) 212 | K_F8*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F8) 213 | K_F9*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F9) 214 | K_F10*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F10) 215 | K_F11*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F11) 216 | K_F12*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F12) 217 | 218 | K_PRINTSCREEN*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRINTSCREEN) 219 | K_SCROLLLOCK*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SCROLLLOCK) 220 | K_PAUSE*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAUSE) 221 | K_INSERT*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_INSERT) 222 | K_HOME*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HOME) 223 | K_PAGEUP*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEUP) 224 | K_END*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_END) 225 | K_PAGEDOWN*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEDOWN) 226 | K_RIGHT*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RIGHT) 227 | K_LEFT*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LEFT) 228 | K_DOWN*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DOWN) 229 | K_UP*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UP) 230 | 231 | K_NUMLOCKCLEAR*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_NUMLOCKCLEAR) 232 | K_KP_DIVIDE*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DIVIDE) 233 | K_KP_MULTIPLY*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MULTIPLY) 234 | K_KP_MINUS*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MINUS) 235 | K_KP_PLUS*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUS) 236 | K_KP_ENTER*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_ENTER) 237 | K_KP_1*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_1) 238 | K_KP_2*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_2) 239 | K_KP_3*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_3) 240 | K_KP_4*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_4) 241 | K_KP_5*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_5) 242 | K_KP_6*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_6) 243 | K_KP_7*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_7) 244 | K_KP_8*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_8) 245 | K_KP_9*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_9) 246 | K_KP_0*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_0) 247 | K_KP_PERIOD*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERIOD) 248 | 249 | K_APPLICATION*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APPLICATION) 250 | K_POWER*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_POWER) 251 | K_KP_EQUALS*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALS) 252 | K_F13*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F13) 253 | K_F14*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F14) 254 | K_F15*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F15) 255 | K_F16*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F16) 256 | K_F17*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F17) 257 | K_F18*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F18) 258 | K_F19*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F19) 259 | K_F20*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F20) 260 | K_F21*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F21) 261 | K_F22*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F22) 262 | K_F23*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F23) 263 | K_F24*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F24) 264 | K_EXECUTE*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXECUTE) 265 | K_HELP*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HELP) 266 | K_MENU*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MENU) 267 | K_SELECT*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SELECT) 268 | K_STOP*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_STOP) 269 | K_AGAIN*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AGAIN) 270 | K_UNDO*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UNDO) 271 | K_CUT*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CUT) 272 | K_COPY*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COPY) 273 | K_PASTE*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PASTE) 274 | K_FIND*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_FIND) 275 | K_MUTE*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MUTE) 276 | K_VOLUMEUP*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEUP) 277 | K_VOLUMEDOWN*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEDOWN) 278 | K_KP_COMMA*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COMMA) 279 | K_KP_EQUALSAS400*: cint = 280 | SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALSAS400) 281 | 282 | K_ALTERASE*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_ALTERASE) 283 | K_SYSREQ*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SYSREQ) 284 | K_CANCEL*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CANCEL) 285 | K_CLEAR*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEAR) 286 | K_PRIOR*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRIOR) 287 | K_RETURN2*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RETURN2) 288 | K_SEPARATOR*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SEPARATOR) 289 | K_OUT*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OUT) 290 | K_OPER*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OPER) 291 | K_CLEARAGAIN*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEARAGAIN) 292 | K_CRSEL*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CRSEL) 293 | K_EXSEL*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXSEL) 294 | 295 | K_KP_00*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_00) 296 | K_KP_000*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_000) 297 | K_THOUSANDSSEPARATOR*: cint = 298 | SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_THOUSANDSSEPARATOR) 299 | K_DECIMALSEPARATOR*: cint = 300 | SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DECIMALSEPARATOR) 301 | K_CURRENCYUNIT*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYUNIT) 302 | K_CURRENCYSUBUNIT*: cint = 303 | SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYSUBUNIT) 304 | K_KP_LEFTPAREN*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTPAREN) 305 | K_KP_RIGHTPAREN*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTPAREN) 306 | K_KP_LEFTBRACE*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTBRACE) 307 | K_KP_RIGHTBRACE*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTBRACE) 308 | K_KP_TAB*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_TAB) 309 | K_KP_BACKSPACE*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BACKSPACE) 310 | K_KP_A*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_A) 311 | K_KP_B*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_B) 312 | K_KP_C*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_C) 313 | K_KP_D*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_D) 314 | K_KP_E*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_E) 315 | K_KP_F*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_F) 316 | K_KP_XOR*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_XOR) 317 | K_KP_POWER*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_POWER) 318 | K_KP_PERCENT*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERCENT) 319 | K_KP_LESS*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LESS) 320 | K_KP_GREATER*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_GREATER) 321 | K_KP_AMPERSAND*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AMPERSAND) 322 | K_KP_DBLAMPERSAND*: cint = 323 | SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLAMPERSAND) 324 | K_KP_VERTICALBAR*: cint = 325 | SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_VERTICALBAR) 326 | K_KP_DBLVERTICALBAR*: cint = 327 | SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLVERTICALBAR) 328 | K_KP_COLON*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COLON) 329 | K_KP_HASH*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HASH) 330 | K_KP_SPACE*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_SPACE) 331 | K_KP_AT*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AT) 332 | K_KP_EXCLAM*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EXCLAM) 333 | K_KP_MEMSTORE*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSTORE) 334 | K_KP_MEMRECALL*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMRECALL) 335 | K_KP_MEMCLEAR*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMCLEAR) 336 | K_KP_MEMADD*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMADD) 337 | K_KP_MEMSUBTRACT*: cint = 338 | SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSUBTRACT) 339 | K_KP_MEMMULTIPLY*: cint = 340 | SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMMULTIPLY) 341 | K_KP_MEMDIVIDE*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMDIVIDE) 342 | K_KP_PLUSMINUS*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUSMINUS) 343 | K_KP_CLEAR*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEAR) 344 | K_KP_CLEARENTRY*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEARENTRY) 345 | K_KP_BINARY*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BINARY) 346 | K_KP_OCTAL*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_OCTAL) 347 | K_KP_DECIMAL*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DECIMAL) 348 | K_KP_HEXADECIMAL*: cint = 349 | SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HEXADECIMAL) 350 | 351 | K_LCTRL*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LCTRL) 352 | K_LSHIFT*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LSHIFT) 353 | K_LALT*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LALT) 354 | K_LGUI*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LGUI) 355 | K_RCTRL*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RCTRL) 356 | K_RSHIFT*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RSHIFT) 357 | K_RALT*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RALT) 358 | K_RGUI*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RGUI) 359 | 360 | K_MODE*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MODE) 361 | 362 | K_AUDIONEXT*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIONEXT) 363 | K_AUDIOPREV*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPREV) 364 | K_AUDIOSTOP*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOSTOP) 365 | K_AUDIOPLAY*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPLAY) 366 | K_AUDIOMUTE*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOMUTE) 367 | K_MEDIASELECT*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIASELECT) 368 | K_WWW*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_WWW) 369 | K_MAIL*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MAIL) 370 | K_CALCULATOR*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CALCULATOR) 371 | K_COMPUTER*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COMPUTER) 372 | K_AC_SEARCH*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_SEARCH) 373 | K_AC_HOME*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_HOME) 374 | K_AC_BACK*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BACK) 375 | K_AC_FORWARD*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_FORWARD) 376 | K_AC_STOP*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_STOP) 377 | K_AC_REFRESH*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_REFRESH) 378 | K_AC_BOOKMARKS*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BOOKMARKS) 379 | 380 | K_BRIGHTNESSDOWN*: cint = 381 | SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_BRIGHTNESSDOWN) 382 | K_BRIGHTNESSUP*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_BRIGHTNESSUP) 383 | K_DISPLAYSWITCH*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DISPLAYSWITCH) 384 | K_KBDILLUMTOGGLE*: cint = 385 | SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMTOGGLE) 386 | K_KBDILLUMDOWN*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMDOWN) 387 | K_KBDILLUMUP*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMUP) 388 | K_EJECT*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EJECT) 389 | K_SLEEP*: cint = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SLEEP) 390 | 391 | type 392 | Keymod* {.size: sizeof(cint).} = enum 393 | KMOD_NONE = 0x0000, KMOD_LSHIFT = 0x0001, KMOD_RSHIFT = 0x0002, 394 | KMOD_LCTRL= 0x0040, KMOD_RCTRL = 0x0080, KMOD_LALT = 0x0100, 395 | KMOD_RALT = 0x0200, KMOD_LGUI = 0x0400, KMOD_RGUI = 0x0800, 396 | KMOD_NUM = 0x1000, KMOD_CAPS = 0x2000, KMOD_MODE = 0x4000, 397 | KMOD_RESERVED=0x8000 398 | 399 | converter toInt*(some: Keymod): cint = cint(some) 400 | 401 | template KMOD_CTRL*: untyped = (KMOD_LCTRL or KMOD_RCTRL) 402 | template KMOD_SHIFT*:untyped = (KMOD_LSHIFT or KMOD_RSHIFT) 403 | template KMOD_ALT*: untyped = (KMOD_LALT or KMOD_RALT) 404 | template KMOD_GUI*: untyped = (KMOD_LGUI or KMOD_RGUI) 405 | 406 | {.deprecated: [TScancode: Scancode].} 407 | {.deprecated: [TKeymod: Keymod].} 408 | 409 | 410 | -------------------------------------------------------------------------------- /src/sdl2/ttf.nim: -------------------------------------------------------------------------------- 1 | ## TrueType font rendering library. 2 | ## 3 | ## **Note:** 4 | ## In many places, ttf will say "glyph" when it means "code point." 5 | ## Unicode is hard, we learn as we go, and we apologize for adding to the 6 | ## confusion. 7 | 8 | when not defined(SDL_Static): 9 | when defined(windows): 10 | const LibName* = "SDL2_ttf.dll" 11 | elif defined(macosx): 12 | const LibName = "libSDL2_ttf.dylib" 13 | else: 14 | const LibName = "libSDL2_ttf(|-2.0).so(|.0)" 15 | else: 16 | static: echo "SDL_Static option is deprecated and will soon be removed. Instead please use --dynlibOverride:SDL2." 17 | 18 | import sdl2 19 | 20 | type 21 | FontPtr* {.pure.} = ptr object 22 | ## The internal structure containing font information 23 | 24 | when not defined(SDL_Static): 25 | {.push callConv:cdecl, dynlib:LibName.} 26 | 27 | proc ttfLinkedVersion*(): ptr SDL_version {.importc: "TTF_Linked_Version".} 28 | ## This procedure gets the version of the dynamically linked ttf library. 29 | # TODO Add an equivalent of the `TTF_VERSION` macro (version template ?) 30 | # and this comment: 31 | # It should NOT be used to fill a version structure, instead you should 32 | # use the `version()` template. 33 | 34 | # ZERO WIDTH NO-BREAKSPACE (Unicode byte order mark) 35 | const 36 | UNICODE_BOM_NATIVE* = 0x0000FEFF 37 | UNICODE_BOM_SWAPPED* = 0x0000FFFE 38 | 39 | proc ttfByteSwappedUnicode*(swapped: cint) {.importc: "TTF_ByteSwappedUNICODE".} 40 | ## This procedure tells the library whether UNICODE text is generally 41 | ## byteswapped. A UNICODE BOM character in a string will override 42 | ## this setting for the remainder of that string. 43 | 44 | proc ttfInit*(): SDL_Return {.importc: "TTF_Init", discardable.} 45 | ## Initialize the TTF engine. 46 | ## 47 | ## `Return` `0` if successful, `-1` on error. 48 | 49 | proc openFont*(file: cstring; ptsize: cint): FontPtr {.importc: "TTF_OpenFont".} 50 | ## Open a font file and create a font of the specified point size. 51 | ## Some .fon fonts will have several sizes embedded in the file, so the 52 | ## point size becomes the index of choosing which size. If the value 53 | ## is too high, the last indexed size will be the default. 54 | ## 55 | ## **See also:** 56 | ## * `openFontIndex proc<#openFontIndex,cstring,cint,clong>`_ 57 | ## * `openFontRW proc<#openFontRW,ptr.RWops,cint,cint>`_ 58 | ## * `openFontIndexRW proc<#openFontIndexRW,ptr.RWops,cint,cint,clong>`_ 59 | 60 | proc openFontIndex*(file: cstring; ptsize: cint; index: clong): FontPtr {. 61 | importc: "TTF_OpenFontIndex".} 62 | proc openFontRW*(src: ptr RWops; freesrc: cint; ptsize: cint): FontPtr {. 63 | importc: "TTF_OpenFontRW".} 64 | proc openFontIndexRW*(src: ptr RWops; freesrc: cint; ptsize: cint; 65 | index: clong): FontPtr {.importc: "TTF_OpenFontIndexRW".} 66 | # Set and retrieve the font style 67 | const 68 | TTF_STYLE_NORMAL* = 0x00000000 69 | TTF_STYLE_BOLD* = 0x00000001 70 | TTF_STYLE_ITALIC* = 0x00000002 71 | TTF_STYLE_UNDERLINE* = 0x00000004 72 | TTF_STYLE_STRIKETHROUGH* = 0x00000008 73 | 74 | proc getFontStyle*(font: FontPtr): cint {.importc: "TTF_GetFontStyle".} 75 | proc getStyle*(font: FontPtr): cint {.importc: "TTF_GetFontStyle".} 76 | proc setFontStyle*(font: FontPtr; style: cint) {.importc: "TTF_SetFontStyle".} 77 | proc setStyle*(font: FontPtr; style: cint) {.importc: "TTF_SetFontStyle".} 78 | proc getFontOutline*(font: FontPtr): cint {.importc: "TTF_GetFontOutline".} 79 | proc getOutline*(font: FontPtr): cint {.importc: "TTF_GetFontOutline".} 80 | proc setFontOutline*(font: FontPtr; outline: cint) {.importc: "TTF_SetFontOutline".} 81 | proc setOutline*(font: FontPtr; outline: cint) {.importc: "TTF_SetFontOutline".} 82 | 83 | # Set and retrieve FreeType hinter settings 84 | const 85 | TTF_HINTING_NORMAL* = 0 86 | TTF_HINTING_LIGHT* = 1 87 | TTF_HINTING_MONO* = 2 88 | TTF_HINTING_NONE* = 3 89 | TTF_HINTING_LIGHT_SUBPIXEL* = 4 90 | proc getFontHinting*(font: FontPtr): cint {.importc: "TTF_GetFontHinting".} 91 | proc getHinting*(font: FontPtr): cint {.importc: "TTF_GetFontHinting".} 92 | 93 | proc setFontHinting*(font: FontPtr; hinting: cint) {.importc: "TTF_SetFontHinting".} 94 | proc setHinting*(font: FontPtr; hinting: cint) {.importc: "TTF_SetFontHinting".} 95 | 96 | proc fontHeight*(font: FontPtr): cint {.importc: "TTF_FontHeight".} 97 | proc height*(font: FontPtr): cint {.importc: "TTF_FontHeight".} 98 | ## Get the total height of the font - usually equal to point size. 99 | 100 | proc fontAscent*(font: FontPtr): cint {.importc: "TTF_FontAscent".} 101 | proc ascent*(font: FontPtr): cint {.importc: "TTF_FontAscent".} 102 | ## Get the offset from the baseline to the top of the font. 103 | ## 104 | ## This is a positive value, relative to the baseline. 105 | 106 | proc fontDescent*(font: FontPtr): cint {.importc: "TTF_FontDescent".} 107 | proc descent*(font: FontPtr): cint {.importc: "TTF_FontDescent".} 108 | ## Get the offset from the baseline to the bottom of the font. 109 | ## 110 | ## This is a negative value, relative to the baseline. 111 | 112 | proc fontLineSkip*(font: FontPtr): cint {.importc: "TTF_FontLineSkip".} 113 | proc lineSkip*(font: FontPtr): cint {.importc: "TTF_FontLineSkip".} 114 | ## Get the recommended spacing between lines of text for this font. 115 | 116 | proc getFontKerning*(font: FontPtr): cint {.importc: "TTF_GetFontKerning".} 117 | proc getKerning*(font: FontPtr): cint {.importc: "TTF_GetFontKerning".} 118 | ## Get whether or not kerning is allowed for this font. 119 | 120 | proc setFontKerning*(font: FontPtr; allowed: cint) {.importc: "TTF_SetFontKerning".} 121 | proc setKerning*(font: FontPtr; allowed: cint) {.importc: "TTF_SetFontKerning".} 122 | ## Set whether or not kerning is allowed for this font. 123 | 124 | proc fontFaces*(font: FontPtr): clong {.importc: "TTF_FontFaces".} 125 | ## Get the number of faces of the font. 126 | 127 | proc fontFaceIsFixedWidth*(font: FontPtr): cint {.importc: "TTF_FontFaceIsFixedWidth".} 128 | ## Get the font face attributes, if any. 129 | 130 | proc fontFaceFamilyName*(font: FontPtr): cstring {.importc: "TTF_FontFaceFamilyName".} 131 | proc fontFaceStyleName*(font: FontPtr): cstring {.importc: "TTF_FontFaceStyleName".} 132 | 133 | proc glyphIsProvided*(font: FontPtr; ch: uint16): cint {. 134 | importc: "TTF_GlyphIsProvided".} 135 | ## Check wether a glyph is provided by the font or not. 136 | 137 | proc glyphMetrics*(font: FontPtr; ch: uint16; minx: ptr cint; 138 | maxx: ptr cint; miny: ptr cint; maxy: ptr cint; 139 | advance: ptr cint): cint {.importc: "TTF_GlyphMetrics".} 140 | ## Get the metrics (dimensions) of a glyph. 141 | ## 142 | ## To understand what these metrics mean, here is a useful link: 143 | ## 144 | ## http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html 145 | 146 | proc sizeText*(font: FontPtr; text: cstring; w: ptr cint; h: ptr cint): cint{. 147 | importc: "TTF_SizeText".} 148 | ## Get the dimensions of a rendered string of text. 149 | ## 150 | ## **See also:** 151 | ## * `sizeUtf8 proc<#sizeUtf8,FontPtr,cstring,ptr.cint,ptr.cint>`_ 152 | ## * `sizeUnicode proc<#sizeUnicode,FontPtr,ptr.uint16,ptr.cint,ptr.cint>`_ 153 | 154 | proc sizeUtf8*(font: FontPtr; text: cstring; w: ptr cint; h: ptr cint): cint{. 155 | importc: "TTF_SizeUTF8".} 156 | proc sizeUnicode*(font: FontPtr; text: ptr uint16; w, h: ptr cint): cint{. 157 | importc: "TTF_SizeUNICODE".} 158 | # Create an 8-bit palettized surface and render the given text at 159 | # fast quality with the given font and color. The 0 pixel is the 160 | # colorkey, giving a transparent background, and the 1 pixel is set 161 | # to the text color. 162 | # This function returns the new surface, or NULL if there was an error. 163 | # 164 | proc renderTextSolid*(font: FontPtr; text: cstring; fg: Color): SurfacePtr{. 165 | importc: "TTF_RenderText_Solid".} 166 | ## Create an 8-bit palettized surface and render the given text at 167 | ## fast quality with the given font and color. The 0 pixel is the 168 | ## colorkey, giving a transparent background, and the 1 pixel is set 169 | ## to the text color. 170 | ## 171 | ## `Return` the new surface, or `nil` if there was an error. 172 | ## 173 | ## **See also:** 174 | ## * `renderUtf8Solid proc<#renderUtf8Solid,FontPtr,cstring,Color>`_ 175 | ## * `renderUnicodeSolid proc<#renderUnicodeSolid,FontPtr,ptr.uint16,Color>`_ 176 | 177 | proc renderUtf8Solid*(font: FontPtr; text: cstring; fg: Color): SurfacePtr{. 178 | importc: "TTF_RenderUTF8_Solid".} 179 | proc renderUnicodeSolid*(font: FontPtr; text: ptr uint16; 180 | fg: Color): SurfacePtr {.importc: "TTF_RenderUNICODE_Solid".} 181 | 182 | proc renderGlyphSolid*(font: FontPtr; ch: uint16; fg: Color): SurfacePtr {. 183 | importc: "TTF_RenderGlyph_Solid".} 184 | ## Create an 8-bit palettized surface and render the given glyph at 185 | ## fast quality with the given font and color. The 0 pixel is the 186 | ## colorkey, giving a transparent background, and the 1 pixel is set 187 | ## to the text color. 188 | ## 189 | ## The glyph is rendered without any padding or centering in the X 190 | ## direction, and aligned normally in the Y direction. 191 | ## 192 | ## `Return` the new surface, or `nil` if there was an error. 193 | 194 | proc renderTextShaded*(font: FontPtr; text: cstring; 195 | fg, bg: Color): SurfacePtr {.importc: "TTF_RenderText_Shaded".} 196 | ## Create an 8-bit palettized surface and render the given text at 197 | ## high quality with the given font and colors. The 0 pixel is background, 198 | ## while other pixels have varying degrees of the foreground color. 199 | ## 200 | ## `Return` the new surface, or `nil` if there was an error. 201 | ## 202 | ## **See also:** 203 | ## * `renderUtf8Shaded proc<#renderUtf8Shaded,FontPtr,cstring,Color,Color>`_ 204 | ## * `renderUnicodeShaded proc<#renderUnicodeShaded,FontPtr,ptr.uint16,Color,Color>`_ 205 | 206 | proc renderUtf8Shaded*(font: FontPtr; text: cstring; fg, bg: Color): SurfacePtr {. 207 | importc: "TTF_RenderUTF8_Shaded".} 208 | proc renderUnicodeShaded*(font: FontPtr; text: ptr uint16; 209 | fg, bg: Color): SurfacePtr {.importc: "TTF_RenderUNICODE_Shaded".} 210 | 211 | proc renderGlyphShaded*(font: FontPtr; ch: uint16; fg, bg: Color): SurfacePtr {. 212 | importc: "TTF_RenderGlyph_Shaded".} 213 | ## Create an 8-bit palettized surface and render the given glyph at 214 | ## high quality with the given font and colors. The 0 pixel is background, 215 | ## while other pixels have varying degrees of the foreground color. 216 | ## 217 | ## The glyph is rendered without any padding or centering in the X 218 | ## direction, and aligned normally in the Y direction. 219 | ## 220 | ## `Return` the new surface, or `nil` if there was an error. 221 | 222 | proc renderTextBlended*(font: FontPtr; text: cstring; fg: Color): SurfacePtr {. 223 | importc: "TTF_RenderText_Blended".} 224 | ## Create a 32-bit ARGB surface and render the given text at high quality, 225 | ## using alpha blending to dither the font with the given color. 226 | ## 227 | ## `Return` the new surface, or `nil` if there was an error. 228 | ## 229 | ## **See also:** 230 | ## * `renderUtf8Blended proc<#renderUtf8Blended,FontPtr,cstring,Color>`_ 231 | ## * `renderUnicodeBlended proc<#renderUnicodeBlended,FontPtr,ptr.uint16,Color>`_ 232 | 233 | proc renderUtf8Blended*(font: FontPtr; text: cstring; fg: Color): SurfacePtr {. 234 | importc: "TTF_RenderUTF8_Blended".} 235 | proc renderUnicodeBlended*(font: FontPtr; text: ptr uint16; 236 | fg: Color): SurfacePtr {.importc: "TTF_RenderUNICODE_Blended".} 237 | 238 | proc renderTextBlendedWrapped*(font: FontPtr; text: cstring; fg: Color; 239 | wrapLength: uint32): SurfacePtr {.importc: "TTF_RenderText_Blended_Wrapped".} 240 | ## Create a 32-bit ARGB surface and render the given text at high quality, 241 | ## using alpha blending to dither the font with the given color. 242 | ## Text is wrapped to multiple lines on line endings and on word boundaries 243 | ## if it extends beyond wrapLength in pixels. 244 | ## 245 | ## `Return` the new surface, or `nil` if there was an error. 246 | ## 247 | ## **See also:** 248 | ## * `renderUtf8BlendedWrapped proc<#renderUtf8BlendedWrapped,FontPtr,cstring,Color,uint32>`_ 249 | ## * `renderUnicodeBlendedWrapped proc<#renderUnicodeBlendedWrapped,FontPtr,ptr.uint16,Color,uint32>`_ 250 | 251 | proc renderUtf8BlendedWrapped*(font: FontPtr; text: cstring; fg: Color; 252 | wrapLength: uint32): SurfacePtr {.importc: "TTF_RenderUTF8_Blended_Wrapped".} 253 | proc renderUnicodeBlendedWrapped*(font: FontPtr; text: ptr uint16; fg: Color; 254 | wrapLength: uint32): SurfacePtr {.importc: "TTF_RenderUNICODE_Blended_Wrapped".} 255 | 256 | proc renderGlyphBlended*(font: FontPtr; ch: uint16; fg: Color): SurfacePtr {. 257 | importc: "TTF_RenderGlyph_Blended".} 258 | ## Create a 32-bit ARGB surface and render the given glyph at high quality, 259 | ## using alpha blending to dither the font with the given color. 260 | ## The glyph is rendered without any padding or centering in the X 261 | ## direction, and aligned normally in the Y direction. 262 | ## 263 | ## `Return` the new surface, or `nil` if there was an error. 264 | 265 | 266 | proc close*(font: FontPtr) {.importc: "TTF_CloseFont".} 267 | ## Close an opened font file. 268 | 269 | proc ttfQuit*() {.importc: "TTF_Quit".} 270 | ## De-initialize the TTF engine. 271 | 272 | proc ttfWasInit*(): bool {.importc: "TTF_WasInit".} 273 | ## Check if the TTF engine is initialized. 274 | 275 | proc getFontKerningSize*(font: FontPtr; prev_index, indx: cint): cint {. 276 | importc: "TTF_GetFontKerningSize".} 277 | ## Get the kerning size of two glyphs indices. 278 | 279 | when not defined(SDL_Static): 280 | {.pop.} 281 | 282 | 283 | proc renderText*(font: FontPtr; text: cstring; fg, bg: Color): SurfacePtr = 284 | renderTextShaded(font, text, fg, bg) 285 | --------------------------------------------------------------------------------