├── examples ├── sdl_opengl_and_sokol │ ├── v.mod │ ├── .gitignore │ ├── example_shader.glsl │ └── main.v ├── basic_window │ ├── .gitignore │ └── main.v ├── tvintris │ ├── .gitignore │ └── README.md ├── lbm │ ├── profiles │ │ ├── test.png │ │ ├── barrier.png │ │ ├── circle.png │ │ ├── septum.png │ │ └── asymetric.png │ ├── v.mod │ ├── readme.md │ ├── colormap.v │ ├── cell.v │ ├── lattice.v │ └── main.v ├── assets │ ├── images │ │ ├── v-logo.jpg │ │ ├── v-logo.png │ │ ├── v-logo.webp │ │ ├── tvintris.png │ │ ├── v-logo_30_30.png │ │ ├── v-logo.lossless.webp │ │ └── v-logo.svg │ ├── sounds │ │ ├── block.wav │ │ ├── single.wav │ │ ├── triple.wav │ │ ├── IcyGarden.mid │ │ ├── sound_01.wav │ │ ├── sound_02.mp3 │ │ ├── sound_03.flac │ │ ├── sound_04.ogg │ │ └── TwintrisThosenine.mod │ └── fonts │ │ └── RobotoMono-Regular.ttf ├── version │ └── main.v ├── versions │ └── main.v ├── basic_image │ └── basic_image.v └── basic_mixer │ └── basic_mixer.v ├── a_types.c.v ├── .gitignore ├── image ├── README.md ├── c.c.v └── image.c.v ├── v.mod ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── PULL_REQUEST_TEMPLATE └── workflows │ └── ci.yml ├── sdl.v ├── main_ios.c.v ├── platform.c.v ├── bits.c.v ├── endian.c.v ├── ttf └── c.c.v ├── mixer └── c.c.v ├── LICENSE ├── quit.c.v ├── c ├── sdl.c.v └── memory.c.v ├── main.c.v ├── setup.vsh ├── system_linux.c.v ├── tests └── crash_with_gc.vv ├── misc.c.v ├── windows_install_dependencies.vsh ├── power.c.v ├── guid.c.v ├── loadso.c.v ├── system.c.v ├── metal.c.v ├── locale.c.v ├── gesture.c.v ├── main_windows.c.v ├── system_ios.c.v ├── error.c.v ├── clipboard.c.v ├── touch.c.v ├── filesystem.c.v ├── shape.c.v ├── README.md ├── version.c.v ├── messagebox.c.v ├── system_windows.c.v ├── sdl.c.v ├── timer.c.v ├── vulkan └── vulkan.c.v ├── log.c.v ├── blendmode.c.v └── system_android_outside_termux.c.v /examples/sdl_opengl_and_sokol/v.mod: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/basic_window/.gitignore: -------------------------------------------------------------------------------- 1 | main 2 | -------------------------------------------------------------------------------- /examples/tvintris/.gitignore: -------------------------------------------------------------------------------- 1 | tvintris 2 | -------------------------------------------------------------------------------- /examples/sdl_opengl_and_sokol/.gitignore: -------------------------------------------------------------------------------- 1 | main 2 | -------------------------------------------------------------------------------- /a_types.c.v: -------------------------------------------------------------------------------- 1 | module sdl 2 | 3 | // va_list 4 | @[typedef] 5 | pub struct C.va_list {} 6 | -------------------------------------------------------------------------------- /examples/lbm/profiles/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/lbm/profiles/test.png -------------------------------------------------------------------------------- /examples/assets/images/v-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/assets/images/v-logo.jpg -------------------------------------------------------------------------------- /examples/assets/images/v-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/assets/images/v-logo.png -------------------------------------------------------------------------------- /examples/assets/images/v-logo.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/assets/images/v-logo.webp -------------------------------------------------------------------------------- /examples/assets/sounds/block.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/assets/sounds/block.wav -------------------------------------------------------------------------------- /examples/assets/sounds/single.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/assets/sounds/single.wav -------------------------------------------------------------------------------- /examples/assets/sounds/triple.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/assets/sounds/triple.wav -------------------------------------------------------------------------------- /examples/lbm/profiles/barrier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/lbm/profiles/barrier.png -------------------------------------------------------------------------------- /examples/lbm/profiles/circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/lbm/profiles/circle.png -------------------------------------------------------------------------------- /examples/lbm/profiles/septum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/lbm/profiles/septum.png -------------------------------------------------------------------------------- /examples/assets/images/tvintris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/assets/images/tvintris.png -------------------------------------------------------------------------------- /examples/assets/sounds/IcyGarden.mid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/assets/sounds/IcyGarden.mid -------------------------------------------------------------------------------- /examples/assets/sounds/sound_01.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/assets/sounds/sound_01.wav -------------------------------------------------------------------------------- /examples/assets/sounds/sound_02.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/assets/sounds/sound_02.mp3 -------------------------------------------------------------------------------- /examples/assets/sounds/sound_03.flac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/assets/sounds/sound_03.flac -------------------------------------------------------------------------------- /examples/assets/sounds/sound_04.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/assets/sounds/sound_04.ogg -------------------------------------------------------------------------------- /examples/lbm/profiles/asymetric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/lbm/profiles/asymetric.png -------------------------------------------------------------------------------- /examples/assets/images/v-logo_30_30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/assets/images/v-logo_30_30.png -------------------------------------------------------------------------------- /examples/assets/fonts/RobotoMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/assets/fonts/RobotoMono-Regular.ttf -------------------------------------------------------------------------------- /examples/assets/images/v-logo.lossless.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/assets/images/v-logo.lossless.webp -------------------------------------------------------------------------------- /examples/assets/sounds/TwintrisThosenine.mod: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vlang/sdl/HEAD/examples/assets/sounds/TwintrisThosenine.mod -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore binary files 2 | *.so 3 | *.exe 4 | *.tmp.obj 5 | *.dll 6 | thirdparty/ 7 | 8 | windows_install_dependencies 9 | setup 10 | -------------------------------------------------------------------------------- /image/README.md: -------------------------------------------------------------------------------- 1 | # SDL2 Image Library 2 | Assuming you've installed the dependencies for sdl (already include `SDL2_image` dependency) 3 | 4 | See the Tvintris example for usage 5 | -------------------------------------------------------------------------------- /v.mod: -------------------------------------------------------------------------------- 1 | Module { 2 | name: 'sdl' 3 | description: 'V SDL2 wrapper' 4 | version: '2.30.0' 5 | license: 'MIT' 6 | repo_url: 'https://github.com/vlang/sdl' 7 | dependencies: [] 8 | } 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.v linguist-language=V text=auto eol=lf 2 | *.vv linguist-language=V text=auto eol=lf 3 | *.vsh linguist-language=V text=auto eol=lf 4 | **/v.mod linguist-language=V text=auto eol=lf 5 | -------------------------------------------------------------------------------- /examples/lbm/v.mod: -------------------------------------------------------------------------------- 1 | Module { 2 | name: 'lbm' 3 | description: 'Lattice Boltzmann simulation, used as toy projet to learn about V language' 4 | version: '0.0.1' 5 | license: 'MIT' 6 | dependencies: [] 7 | } 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: 'Feature Request' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/version/main.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | // This can be used in CI to check against the compiled version 4 | import sdl 5 | 6 | fn main() { 7 | mut v := sdl.Version{} 8 | sdl.version(mut v) 9 | println(v.str()) 10 | } 11 | -------------------------------------------------------------------------------- /examples/versions/main.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import sdl 4 | 5 | fn main() { 6 | println('v.mod version ${sdl.vmod_version()}') 7 | println('Const version ${sdl.major_version}.${sdl.minor_version}.${sdl.patchlevel}') 8 | mut compiled_version := sdl.Version{} 9 | sdl.version(mut compiled_version) 10 | println('Compiled against version ${compiled_version.str()}') 11 | mut linked_version := sdl.Version{} 12 | sdl.get_version(mut linked_version) 13 | println('Runtime loaded version ${linked_version.str()}') 14 | } 15 | -------------------------------------------------------------------------------- /sdl.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2019 Nicolas Sauzede. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | import sdl.c 7 | 8 | pub const used_import = c.used_import 9 | 10 | pub fn vmod_version() string { 11 | mut v := '0.0.0' 12 | vmod := @VMOD_FILE 13 | if vmod.len > 0 { 14 | if vmod.contains('version:') { 15 | v = vmod.all_after('version:').all_before('\n').replace("'", '').replace('"', 16 | '').trim(' ') 17 | } 18 | } 19 | return v 20 | } 21 | -------------------------------------------------------------------------------- /examples/tvintris/README.md: -------------------------------------------------------------------------------- 1 | # tVintris 2 | 3 | tvintris.v is a dual-player (local) version based on original source from tetris example by Alex M. 4 | It is largely inspired by ancient game Twintris. 5 | -uses vlib sdl module 6 | 7 | ![tVintris screenshot](images/tvintris.png) 8 | 9 | # how to run tVintris 10 | 11 | `$ v run .` 12 | 13 | # Credits 14 | 15 | Colors, Music and Sounds inspired/ripped from amiga title Twintris (1990 nostalgia !) 16 | - Graphician : Svein Berge 17 | - Musician : Tor Bernhard Gausen (Walkman/Cryptoburners) 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Bug report 4 | title: '' 5 | labels: 'Bug' 6 | assignees: '' 7 | # When updating, make sure to update the template in 'cmd/tools/vbug.v' too 8 | --- 9 | 10 | 12 | 13 | 14 | **V version:** 15 | **OS:** 16 | 17 | **What did you do?** 18 | 19 | 20 | **What did you expect to see?** 21 | 22 | 23 | **What did you see instead?** 24 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE: -------------------------------------------------------------------------------- 1 | 2 | 3 | 33 | -------------------------------------------------------------------------------- /image/c.c.v: -------------------------------------------------------------------------------- 1 | module image 2 | 3 | $if !windows { 4 | // SDL libs are loaded dynamically from Java on Android 5 | $if !android || termux { 6 | // sdl_no_compile_flags allow users to provide 7 | // custom flags (e.g. via CFLAGS/LDFLAGS) for the compiler. 8 | // This is especially useful when building/linking against a 9 | // custom compiled version of the libs on *nix. 10 | $if !sdl_no_compile_flags ? { 11 | #flag -lSDL2_image 12 | } 13 | } 14 | } 15 | 16 | $if x64 { 17 | #flag windows -L @VMODROOT/thirdparty/SDL2_image-2.0.5/lib/x64 18 | } $else { 19 | #flag windows -L @VMODROOT/thirdparty/SDL2_image-2.0.5/lib/x86 20 | } 21 | #flag windows -I @VMODROOT/thirdparty/SDL2_image-2.0.5/include 22 | #flag windows -lSDL2_image 23 | 24 | #include 25 | -------------------------------------------------------------------------------- /examples/basic_window/main.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import sdl 4 | 5 | fn main() { 6 | sdl.init(sdl.init_video) 7 | window := sdl.create_window('Hello SDL2'.str, 300, 300, 500, 300, 0) 8 | renderer := sdl.create_renderer(window, -1, u32(sdl.RendererFlags.accelerated) | u32(sdl.RendererFlags.presentvsync)) 9 | 10 | mut should_close := false 11 | for { 12 | evt := sdl.Event{} 13 | for 0 < sdl.poll_event(&evt) { 14 | match evt.@type { 15 | .quit { should_close = true } 16 | else {} 17 | } 18 | } 19 | if should_close { 20 | break 21 | } 22 | 23 | sdl.set_render_draw_color(renderer, 255, 55, 55, 255) 24 | sdl.render_clear(renderer) 25 | sdl.render_present(renderer) 26 | } 27 | 28 | sdl.destroy_renderer(renderer) 29 | sdl.destroy_window(window) 30 | sdl.quit() 31 | } 32 | -------------------------------------------------------------------------------- /main_ios.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_main.h 8 | // 9 | 10 | fn C.SDL_UIKitRunApp(argc int, argv &&char, main_function MainFunc) int 11 | 12 | // ui_kit_run_app initializes and launches an SDL application. 13 | // 14 | // `argc` The argc parameter from the application's main() function 15 | // `argv` The argv parameter from the application's main() function 16 | // `mainFunction` The SDL app's C-style main(), an SDL_main_func 17 | // returns the return value from mainFunction 18 | // 19 | // NOTE This function is available since SDL 2.0.10. 20 | pub fn ui_kit_run_app(argc int, argv &&char, main_function MainFunc) int { 21 | return C.SDL_UIKitRunApp(argc, argv, main_function) 22 | } 23 | -------------------------------------------------------------------------------- /platform.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_platform.h 8 | // 9 | 10 | fn C.SDL_GetPlatform() &char 11 | 12 | // get_platform gets the name of the platform. 13 | // 14 | // Here are the names returned for some (but not all) supported platforms: 15 | // 16 | // - "Windows" 17 | // - "Mac OS X" 18 | // - "Linux" 19 | // - "iOS" 20 | // - "Android" 21 | // 22 | // returns the name of the platform. If the correct platform name is not 23 | // available, returns a string beginning with the text "Unknown". 24 | // 25 | // NOTE This function is available since SDL 2.0.0. 26 | // 27 | // NOTE the returned &char is const 28 | pub fn get_platform() &char { 29 | return C.SDL_GetPlatform() 30 | } 31 | -------------------------------------------------------------------------------- /bits.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_bits.h 8 | // 9 | // NOTE not all distros include this file 10 | 11 | /* 12 | fn C.SDL_MostSignificantBitIndex32(x u32) int 13 | 14 | // most_significant_bit_index32 gets the index of the most significant bit. Result is undefined when called 15 | // with 0. This operation can also be stated as "count leading zeroes" and 16 | // "log base 2". 17 | // 18 | // returns index of the most significant bit, or -1 if the value is 0. 19 | pub fn most_significant_bit_index32(x u32) int { 20 | return C.SDL_MostSignificantBitIndex32(x) 21 | } 22 | 23 | fn C.SDL_HasExactlyOneBitSet32(x u32) bool 24 | pub fn has_exactly_one_bit_set32(x u32) bool { 25 | return C.SDL_HasExactlyOneBitSet32(x) 26 | } 27 | */ 28 | -------------------------------------------------------------------------------- /endian.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_endian.h 8 | // 9 | 10 | pub const lil_endian = C.SDL_LIL_ENDIAN 11 | pub const big_endian = C.SDL_BIG_ENDIAN 12 | pub const byteorder = C.SDL_BYTEORDER 13 | 14 | // TODO SDL_endian.h fails on `tcc` with: 15 | // 2.0.18/include/SDL2/SDL_endian.h:125: error: unknown constraint 'Q' 16 | // fn C.SDL_Swap16(x u16) u16 17 | // pub fn swap16(x u16) u16 { 18 | // return C.SDL_Swap16(x) 19 | // } 20 | 21 | fn C.SDL_Swap32(x u32) u32 22 | pub fn swap32(x u32) u32 { 23 | return C.SDL_Swap32(x) 24 | } 25 | 26 | fn C.SDL_Swap64(x u64) u64 27 | pub fn swap64(x u64) u64 { 28 | return C.SDL_Swap64(x) 29 | } 30 | 31 | fn C.SDL_SwapFloat(x f32) f32 32 | pub fn swap_float(x f32) f32 { 33 | return C.SDL_SwapFloat(x) 34 | } 35 | -------------------------------------------------------------------------------- /ttf/c.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module ttf 5 | 6 | $if !windows { 7 | // SDL libs are loaded dynamically from Java on Android 8 | $if !android || termux { 9 | // sdl_no_compile_flags allow users to provide 10 | // custom flags (e.g. via CFLAGS/LDFLAGS) for the compiler. 11 | // This is especially useful when building/linking against a 12 | // custom compiled version of the libs on *nix. 13 | $if !sdl_no_compile_flags ? { 14 | #flag -lSDL2_ttf 15 | } 16 | } 17 | } 18 | 19 | $if x64 { 20 | #flag windows -L @VMODROOT/thirdparty/SDL2_ttf-2.0.15/lib/x64 21 | } $else { 22 | #flag windows -L @VMODROOT/thirdparty/SDL2_ttf-2.0.15/lib/x86 23 | } 24 | 25 | #flag windows -I @VMODROOT/thirdparty/SDL2_ttf-2.0.15/include 26 | #flag windows -lSDL2_ttf 27 | 28 | #include 29 | -------------------------------------------------------------------------------- /mixer/c.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module mixer 5 | 6 | $if !windows { 7 | // SDL libs are loaded dynamically from Java on Android 8 | $if !android || termux { 9 | // sdl_no_compile_flags allow users to provide 10 | // custom flags (e.g. via CFLAGS/LDFLAGS) for the compiler. 11 | // This is especially useful when building/linking against a 12 | // custom compiled version of the libs on *nix. 13 | $if !sdl_no_compile_flags ? { 14 | #flag -lSDL2_mixer 15 | } 16 | } 17 | } 18 | 19 | $if x64 { 20 | #flag windows -L @VMODROOT/thirdparty/SDL2_mixer-2.0.4/lib/x64 21 | } $else { 22 | #flag windows -L @VMODROOT/thirdparty/SDL2_mixer-2.0.4/lib/x86 23 | } 24 | #flag windows -I @VMODROOT/thirdparty/SDL2_mixer-2.0.4/include 25 | #flag windows -lSDL2_mixer 26 | 27 | #include 28 | -------------------------------------------------------------------------------- /examples/sdl_opengl_and_sokol/example_shader.glsl: -------------------------------------------------------------------------------- 1 | // The following defines a vertex shader main function 2 | @vs vs 3 | in vec4 position; 4 | in vec4 color0; 5 | 6 | out vec4 color; 7 | 8 | // You can add more functions here 9 | 10 | void main() { 11 | gl_Position = position; 12 | color = color0; 13 | } 14 | @end 15 | 16 | // The following defines a fragment shader main function 17 | @fs fs 18 | in vec4 color; 19 | out vec4 frag_color; 20 | 21 | // You can add more functions here 22 | 23 | void main() { 24 | frag_color = color; 25 | } 26 | @end 27 | 28 | // The value after `@program` and before `vs fs` decide a part of the name 29 | // of the C function you need to define in V. The value entered is suffixed `_shader_desc` 30 | // in the generated C code. Thus the name for this becomes: `example_shader_desc`. 31 | // In V it's signature then need to be defined as: 32 | // `fn C.simple_shader_desc(gfx.Backend) &gfx.ShaderDesc`. See `simple_shader.v` for the define. 33 | // 34 | // Running `v shader -v .` in this dir will also show you brief information 35 | // about how to use the compiled shader. 36 | @program example vs fs 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Nicolas Sauzede 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 | -------------------------------------------------------------------------------- /examples/lbm/readme.md: -------------------------------------------------------------------------------- 1 | This program is about D2Q9 Lattice Boltzmann Method: 2 | See : https://en.wikipedia.org/wiki/Lattice_Boltzmann_methods 3 | 4 | It's a pet project in order to use V language: https://vlang.io/ 5 | 6 | The simulation is single threaded, probably buggy and should not be used 7 | for serious things. It's very sensible to tau parameter that should be 8 | carefully set. This parameter is related to fluid viscosity, and is set so 9 | that the fluid speed doesn't exceed a speed limit that breaks simulation. 10 | Too narrow passage (speed increased) may reach this limit. 11 | 12 | profiles files MUST be of the same size of defined width and weight and 13 | should be 8bits per pixels. Every non zero value is considered as an 14 | obstacle. 15 | 16 | to compile the program from within source directory: 17 | 18 | v -prod . 19 | 20 | or if you want gcc as compiler: 21 | 22 | v -prod -cc gcc . 23 | 24 | SDL module must be installed: https://vpm.vlang.io/packages/sdl 25 | and post install script executed, see link. 26 | 27 | The simulation is quite slow, but would you like to slow it down, just 28 | uncomment the sdl.delay(...) in file. 29 | 30 | 31 | 32 | This program is released under MIT license. 33 | -------------------------------------------------------------------------------- /quit.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_quit.h 8 | // 9 | 10 | fn C.SDL_QuitRequested() bool 11 | 12 | // An ::SDL_QUIT event is generated when the user tries to close the application 13 | // window. If it is ignored or filtered out, the window will remain open. 14 | // If it is not ignored or filtered, it is queued normally and the window 15 | // is allowed to close. When the window is closed, screen updates will 16 | // complete, but have no effect. 17 | // 18 | // SDL_Init() installs signal handlers for SIGINT (keyboard interrupt) 19 | // and SIGTERM (system termination request), if handlers do not already 20 | // exist, that generate ::SDL_QUIT events as well. There is no way 21 | // to determine the cause of an ::SDL_QUIT event, but setting a signal 22 | // handler in your application will override the default generation of 23 | // quit events for that signal. 24 | // 25 | // See also: SDL_Quit() 26 | // There are no functions directly affecting the quit event 27 | pub fn quit_requested() bool { 28 | return C.SDL_QuitRequested() 29 | } 30 | -------------------------------------------------------------------------------- /c/sdl.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2019 Nicolas Sauzede. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module c 5 | 6 | pub const used_import = 1 7 | 8 | $if !windows { 9 | // SDL libs are loaded dynamically from Java on Android 10 | $if !android || termux { 11 | // sdl_no_compile_flags allow users to provide 12 | // custom flags (e.g. via CFLAGS/LDFLAGS) for the compiler. 13 | // This is especially useful when building/linking against a 14 | // custom compiled version of the libs on *nix. 15 | $if !sdl_no_compile_flags ? { 16 | $if sdl_compat ? { 17 | // Use SDL2 through SDL3 via the compatibility layer 18 | #pkgconfig --cflags --libs sdl2-compat 19 | } $else { 20 | #pkgconfig --cflags --libs sdl2 21 | } 22 | } 23 | } 24 | } $else { 25 | $if tinyc { 26 | #define _STDINT_H_ 27 | #flag -L @VMODROOT/thirdparty 28 | } 29 | } 30 | 31 | #flag -DSDL_DISABLE_IMMINTRIN_H 32 | 33 | $if x64 { 34 | #flag windows -L @VMODROOT/thirdparty/SDL2-2.30.0/lib/x64 35 | } $else { 36 | #flag windows -L @VMODROOT/thirdparty/SDL2-2.30.0/lib/x86 37 | } 38 | 39 | #flag windows -I @VMODROOT/thirdparty/SDL2-2.30.0/include 40 | #flag windows -lSDL2 41 | 42 | #include 43 | -------------------------------------------------------------------------------- /examples/lbm/colormap.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import arrays 4 | 5 | struct Colormap {} 6 | 7 | // build a linear color map ARGB8888 from color c1 to c2, of steps colors 8 | pub fn Colormap.build(c1 u32, c2 u32, steps int) []u32 { 9 | assert steps > 1, 'Error, generating colormap needs at least two steps.' 10 | mut cm := []u32{cap: steps} 11 | 12 | // split c1 & c2 to RGB channels. 13 | mut c1_r := f64((c1 & 0xFF0000) >> 16) 14 | mut c1_g := f64((c1 & 0xFF00) >> 8) 15 | mut c1_b := f64((c1 & 0xFF)) 16 | 17 | c2_r := f64((c2 & 0xFF0000) >> 16) 18 | c2_g := f64((c2 & 0xFF00) >> 8) 19 | c2_b := f64((c2 & 0xFF)) 20 | 21 | delta_r := (c2_r - c1_r) / f64(steps - 1) 22 | delta_g := (c2_g - c1_g) / f64(steps - 1) 23 | delta_b := (c2_b - c1_b) / f64(steps - 1) 24 | 25 | cm << (0xFF000000 | c1) // Emit exact start color. 26 | for _ in 1 .. steps - 1 { 27 | c1_r += delta_r 28 | c1_g += delta_g 29 | c1_b += delta_b 30 | 31 | // Recompose 3 channels to ARGB8888 color. 32 | mut c := u32(0xFF_00_00_00) 33 | c |= u32(c1_r) << 16 34 | c |= u32(c1_g) << 8 35 | c |= u32(c1_b) 36 | cm << c 37 | } 38 | cm << (0xFF000000 | c2) // Emit exact end color. 39 | return cm 40 | } 41 | 42 | // dual creates a color map with start color, intermediate color and final color, equaly sized. 43 | fn Colormap.dual(c1 u32, c2 u32, c3 u32, steps int) []u32 { 44 | assert steps > 2, 'Error, generating dual-colormap needs at least three steps.' 45 | return arrays.append(Colormap.build(c1, c2, steps / 2), Colormap.build(c2, c3, steps - (steps / 2))) 46 | } 47 | -------------------------------------------------------------------------------- /main.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_main.h 8 | // 9 | 10 | // The prototype for the application's main() function 11 | // `typedef int (*SDL_main_func)(int argc, char *argv[]);` 12 | pub type MainFunc = fn (argc int, argv &&char) int 13 | 14 | fn C.SDL_SetMainReady() 15 | 16 | // set_main_ready circumvents failure of SDL_Init() when not using SDL_main() as an entry 17 | // point. 18 | // 19 | // This function is defined in SDL_main.h, along with the preprocessor rule to 20 | // redefine main() as SDL_main(). Thus to ensure that your main() function 21 | // will not be changed it is necessary to define SDL_MAIN_HANDLED before 22 | // including SDL.h. 23 | // 24 | // NOTE This function is available since SDL 2.0.0. 25 | // 26 | // See also: SDL_Init 27 | pub fn set_main_ready() { 28 | C.SDL_SetMainReady() 29 | } 30 | 31 | // TODO 32 | //$if winrt ? { 33 | // fn C.SDL_WinRTRunApp(SDL_main_func MainFunc, reserved voidptr) int 34 | // win_rt_run_app initializes and launch an SDL/WinRT application. 35 | // 36 | // `mainFunction` the SDL app's C-style main(), an SDL_main_func 37 | // `reserved` reserved for future use; should be NULL 38 | // returns 0 on success or -1 on failure; call SDL_GetError() to retrieve 39 | // more information on the failure. 40 | // 41 | // NOTE This function is available since SDL 2.0.3. 42 | // pub fn win_rt_run_app(main_func MainFunc, reserved voidptr) int{ 43 | // return C.SDL_WinRTRunApp(main_func, reserved) 44 | //} 45 | //} 46 | -------------------------------------------------------------------------------- /setup.vsh: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.chdir(os.dir(os.executable()))! 4 | 5 | mut res := os.execute('sdl2-config --version') 6 | if res.exit_code != 0 { 7 | println('sdl2-config is missing. Trying pkg-config...') 8 | pkgconf := os.find_abs_path_of_executable('pkg-config') or { '' } 9 | if !os.is_executable(pkgconf) { 10 | println('pkg-config not found. Giving up') 11 | exit(1) 12 | } 13 | res = os.execute('pkg-config --modversion sdl2') 14 | if res.exit_code != 0 { 15 | println('SDL2 is missing. Trying SDL3...') 16 | res = os.execute('pkg-config --modversion sdl3') 17 | if res.exit_code != 0 { 18 | println('SDL3 is missing. Giving up') 19 | exit(1) 20 | } 21 | } 22 | } 23 | system_version := res.output.trim_space() 24 | println('Your version is ${system_version}') 25 | 26 | remotes := os.execute('git branch -r --list') 27 | if remotes.exit_code != 0 { 28 | println('git is missing. Giving up') 29 | exit(1) 30 | } 31 | supported_versions := remotes.output.split_into_lines().map(it.trim_space()).filter( 32 | it.starts_with('origin/2') || it.starts_with('origin/3')).map(it.all_after('origin/')) 33 | println('The SDL module officially supports these versions of SDL:\n ${supported_versions}') 34 | 35 | if system_version in supported_versions { 36 | println('Setting up the repository to branch ${system_version} that exactly matches your system SDL version') 37 | os.system('git checkout ${system_version}') 38 | exit(0) 39 | } 40 | 41 | base_version := '${system_version.all_before_last('.')}.0' 42 | println('Setting up the repository to branch ${base_version}, that best matches the system SDL version: ${system_version} ...') 43 | os.system('git checkout ${base_version}') 44 | -------------------------------------------------------------------------------- /system_linux.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_system.h 8 | // 9 | 10 | // Platform specific functions for Linux 11 | 12 | fn C.SDL_LinuxSetThreadPriority(thread_id i64, priority int) int 13 | 14 | // linux_set_thread_priority sets the UNIX nice value for a thread. 15 | // 16 | // This uses setpriority() if possible, and RealtimeKit if available. 17 | // 18 | // `threadID` the Unix thread ID to change priority of. 19 | // `priority` The new, Unix-specific, priority value. 20 | // returns 0 on success, or -1 on error. 21 | // 22 | // NOTE This function is available since SDL 2.0.9. 23 | pub fn linux_set_thread_priority(thread_id i64, priority int) int { 24 | return C.SDL_LinuxSetThreadPriority(thread_id, priority) 25 | } 26 | 27 | fn C.SDL_LinuxSetThreadPriorityAndPolicy(thread_id i64, sdl_priority int, sched_policy int) int 28 | 29 | // linux_set_thread_priority_and_policy sets the priority (not nice level) and scheduling policy for a thread. 30 | // 31 | // This uses setpriority() if possible, and RealtimeKit if available. 32 | // 33 | // `threadID` The Unix thread ID to change priority of. 34 | // `sdlPriority` The new SDL_ThreadPriority value. 35 | // `schedPolicy` The new scheduling policy (SCHED_FIFO, SCHED_RR, 36 | // SCHED_OTHER, etc...) 37 | // returns 0 on success, or -1 on error. 38 | // 39 | // NOTE This function is available since SDL 2.0.18. 40 | pub fn linux_set_thread_priority_and_policy(thread_id i64, sdl_priority int, sched_policy int) int { 41 | return C.SDL_LinuxSetThreadPriorityAndPolicy(thread_id, sdl_priority, sched_policy) 42 | } 43 | -------------------------------------------------------------------------------- /tests/crash_with_gc.vv: -------------------------------------------------------------------------------- 1 | // This file serves as a MRE (minimal reproducible example) of a runtime crash triggered by compiling and running 2 | // this file with `v -d sdl_use_gc run ~/.vmodules/sdl/tests/crash_with_gc.vv`. On some setups, the problem seems to be 3 | // memory corruption happening between actions in SDL2's memory allocations and V's default garbage collector. 4 | // Especially when a lot of heap allocations occur. 5 | // 6 | // The example crashes if compiled with `-d sdl_use_gc`. 7 | // See also: https://github.com/vlang/sdl/issues/744 8 | module main 9 | 10 | import sdl 11 | 12 | struct Data1 { 13 | mut: 14 | a int 15 | } 16 | 17 | fn main() { 18 | mut data1 := []&Data1{cap: 200} 19 | for i in 0 .. 200 { 20 | data1 << &Data1{ 21 | a: i 22 | } 23 | } 24 | 25 | sdl.init(sdl.init_video) 26 | window := sdl.create_window('Hello SDL2'.str, 300, 300, 500, 300, 0) 27 | renderer := sdl.create_renderer(window, -1, u32(sdl.RendererFlags.accelerated) | u32(sdl.RendererFlags.presentvsync)) 28 | 29 | mut should_close := false 30 | mut ticks := 0 31 | for { 32 | ticks++ 33 | evt := sdl.Event{} 34 | for 0 < sdl.poll_event(&evt) { 35 | match evt.@type { 36 | .quit { should_close = true } 37 | else {} 38 | } 39 | } 40 | 41 | data1[0].a = ticks 42 | data1.delete(10) 43 | data1 << &Data1{ 44 | a: ticks 45 | } 46 | 47 | println('ticks: ${ticks}') 48 | if should_close || ticks == 1000 { 49 | break 50 | } 51 | 52 | sdl.set_render_draw_color(renderer, 255, 55, 55, 255) 53 | sdl.render_clear(renderer) 54 | sdl.render_present(renderer) 55 | } 56 | println('Exiting. If this was compiled with `-d sdl_use_gc`, an invalid memory access error should occur') 57 | 58 | sdl.destroy_renderer(renderer) 59 | sdl.destroy_window(window) 60 | sdl.quit() 61 | } 62 | -------------------------------------------------------------------------------- /misc.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_misc.h 8 | // 9 | 10 | fn C.SDL_OpenURL(url &char) int 11 | 12 | // open_url opens a URL/URI in the browser or other appropriate external application. 13 | // 14 | // Open a URL in a separate, system-provided application. How this works will 15 | // vary wildly depending on the platform. This will likely launch what makes 16 | // sense to handle a specific URL's protocol (a web browser for `http://`, 17 | // etc), but it might also be able to launch file managers for directories and 18 | // other things. 19 | // 20 | // What happens when you open a URL varies wildly as well: your game window 21 | // may lose focus (and may or may not lose focus if your game was fullscreen 22 | // or grabbing input at the time). On mobile devices, your app will likely 23 | // move to the background or your process might be paused. Any given platform 24 | // may or may not handle a given URL. 25 | // 26 | // If this is unimplemented (or simply unavailable) for a platform, this will 27 | // fail with an error. A successful result does not mean the URL loaded, just 28 | // that we launched _something_ to handle it (or at least believe we did). 29 | // 30 | // All this to say: this function can be useful, but you should definitely 31 | // test it on every platform you target. 32 | // 33 | // `url` A valid URL/URI to open. Use `file:///full/path/to/file` for 34 | // local files, if supported. 35 | // returns 0 on success, or -1 on error; call SDL_GetError() for more 36 | // information. 37 | // 38 | // NOTE This function is available since SDL 2.0.14. 39 | pub fn open_url(url &char) int { 40 | return C.SDL_OpenURL(url) 41 | } 42 | -------------------------------------------------------------------------------- /windows_install_dependencies.vsh: -------------------------------------------------------------------------------- 1 | import os 2 | import compress.szip 3 | import net.http 4 | 5 | const is_terminal = os.is_atty(1) > 0 6 | 7 | const urls = [ 8 | 'https://www.libsdl.org/release/SDL2-devel-2.30.0-VC.zip', 9 | 'https://www.libsdl.org/projects/SDL_ttf/release/SDL2_ttf-devel-2.0.15-VC.zip', 10 | 'https://www.libsdl.org/projects/SDL_image/release/SDL2_image-devel-2.0.5-VC.zip', 11 | 'https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-devel-2.0.4-VC.zip', 12 | ] 13 | 14 | fn main() { 15 | cwd := os.dir(os.executable()) 16 | destination := os.real_path(os.join_path(cwd, 'thirdparty')) 17 | os.mkdir(destination) or {} 18 | for url in urls { 19 | parts := url.split('/') 20 | zip_file := os.join_path(destination, parts.last()) 21 | println('>>> Downloading from: ${url} ... <<<') 22 | download(url, zip_file) or { eprintln('Failed to download ${url}: ${err}') } 23 | println('>>>>>>>> Finished downloading, size: ${os.file_size(zip_file)} .') 24 | if os.exists(zip_file) { 25 | szip.extract_zip_to_dir(zip_file, destination) or { 26 | eprintln('Unable to delete ${zip_file}') 27 | } 28 | os.rm(zip_file) or { println('Unable to delete ${zip_file}') } 29 | } else { 30 | eprintln('Unable to find ${zip_file}') 31 | return 32 | } 33 | } 34 | // Finally, create the SDL2main.def stub file for tcc 35 | stub_file := os.real_path(os.join_path(destination, 'SDL2main.def')) 36 | mut f := os.create(stub_file) or { 37 | eprintln('Unable to create ${stub_file}') 38 | return 39 | } 40 | f.close() 41 | } 42 | 43 | fn download(url string, location string) ! { 44 | $if windows { 45 | http.download_file(url, location)! 46 | return 47 | } 48 | downloader := if is_terminal { 49 | &http.Downloader(http.TerminalStreamingDownloader{}) 50 | } else { 51 | &http.Downloader(http.SilentStreamingDownloader{}) 52 | } 53 | http.download_file_with_progress(url, location, downloader: downloader)! 54 | } 55 | -------------------------------------------------------------------------------- /power.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_power.h 8 | // 9 | 10 | // PowerState is the basic state for the system's power supply. 11 | // PowerState is C.SDL_PowerState 12 | pub enum PowerState { 13 | unknown = C.SDL_POWERSTATE_UNKNOWN // cannot determine power status 14 | on_battery = C.SDL_POWERSTATE_ON_BATTERY // Not plugged in, running on the battery 15 | no_battery = C.SDL_POWERSTATE_NO_BATTERY // Plugged in, no battery available 16 | charging = C.SDL_POWERSTATE_CHARGING // Plugged in, charging battery 17 | charged = C.SDL_POWERSTATE_CHARGED // Plugged in, battery charged 18 | } 19 | 20 | fn C.SDL_GetPowerInfo(seconds &int, percent &int) PowerState 21 | 22 | // get_power_info gets the current power supply details. 23 | // 24 | // You should never take a battery status as absolute truth. Batteries 25 | // (especially failing batteries) are delicate hardware, and the values 26 | // reported here are best estimates based on what that hardware reports. It's 27 | // not uncommon for older batteries to lose stored power much faster than it 28 | // reports, or completely drain when reporting it has 20 percent left, etc. 29 | // 30 | // Battery status can change at any time; if you are concerned with power 31 | // state, you should call this function frequently, and perhaps ignore changes 32 | // until they seem to be stable for a few seconds. 33 | // 34 | // It's possible a platform can only report battery percentage or time left 35 | // but not both. 36 | // 37 | // `seconds` seconds of battery life left, you can pass a NULL here if 38 | // you don't care, will return -1 if we can't determine a 39 | // value, or we're not running on a battery 40 | // `percent` percentage of battery life left, between 0 and 100, you can 41 | // pass a NULL here if you don't care, will return -1 if we 42 | // can't determine a value, or we're not running on a battery 43 | // returns an SDL_PowerState enum representing the current battery state. 44 | // 45 | // NOTE This function is available since SDL 2.0.0. 46 | pub fn get_power_info(seconds &int, percent &int) PowerState { 47 | return PowerState(C.SDL_GetPowerInfo(seconds, percent)) 48 | } 49 | -------------------------------------------------------------------------------- /guid.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_guid.h 8 | // 9 | 10 | // GUID 11 | // An SDL_GUID is a 128-bit identifier for an input device that 12 | // identifies that device across runs of SDL programs on the same 13 | // platform. If the device is detached and then re-attached to a 14 | // different port, or if the base system is rebooted, the device 15 | // should still report the same GUID. 16 | // 17 | // GUIDs are as precise as possible but are not guaranteed to 18 | // distinguish physically distinct but equivalent devices. For 19 | // example, two game controllers from the same vendor with the same 20 | // product ID and revision may have the same GUID. 21 | // 22 | // GUIDs may be platform-dependent (i.e., the same device may report 23 | // different GUIDs on different operating systems). 24 | @[typedef] 25 | struct C.SDL_GUID { 26 | data [16]u8 27 | } 28 | 29 | pub type GUID = C.SDL_GUID 30 | 31 | fn C.SDL_GUIDToString(guid C.SDL_GUID, psz_guid &char, cb_guid int) 32 | 33 | // guid_to_string gets an ASCII string representation for a given ::SDL_GUID. 34 | // 35 | // You should supply at least 33 bytes for pszGUID. 36 | // 37 | // `guid` the ::SDL_GUID you wish to convert to string 38 | // `pszGUID` buffer in which to write the ASCII string 39 | // `cbGUID` the size of pszGUID 40 | // 41 | // NOTE This function is available since SDL 2.24.0. 42 | // 43 | // See also: SDL_GUIDFromString 44 | pub fn guid_to_string(guid GUID, psz_guid &char, cb_guid int) { 45 | C.SDL_GUIDToString(guid, psz_guid, cb_guid) 46 | } 47 | 48 | fn C.SDL_GUIDFromString(const_pch_guid &char) C.SDL_GUID 49 | 50 | // guid_from_string converts a GUID string into a ::SDL_GUID structure. 51 | // 52 | // Performs no error checking. If this function is given a string containing 53 | // an invalid GUID, the function will silently succeed, but the GUID generated 54 | // will not be useful. 55 | // 56 | // `pchGUID` string containing an ASCII representation of a GUID 57 | // returns a ::SDL_GUID structure. 58 | // 59 | // NOTE This function is available since SDL 2.24.0. 60 | // 61 | // See also: SDL_GUIDToString 62 | pub fn guid_from_string(const_pch_guid &char) GUID { 63 | return C.SDL_GUIDFromString(const_pch_guid) 64 | } 65 | -------------------------------------------------------------------------------- /loadso.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_loadso.h 8 | // 9 | fn C.SDL_LoadObject(sofile &char) voidptr 10 | 11 | // load_object dynamicallys load a shared object. 12 | // 13 | // `sofile` a system-dependent name of the object file 14 | // returns an opaque pointer to the object handle or NULL if there was an 15 | // error; call SDL_GetError() for more information. 16 | // 17 | // NOTE This function is available since SDL 2.0.0. 18 | // 19 | // See also: SDL_LoadFunction 20 | // See also: SDL_UnloadObject 21 | pub fn load_object(sofile &char) voidptr { 22 | return C.SDL_LoadObject(sofile) 23 | } 24 | 25 | fn C.SDL_LoadFunction(handle voidptr, const_name &char) voidptr 26 | 27 | // load_function looks up the address of the named function in a shared object. 28 | // 29 | // This function pointer is no longer valid after calling SDL_UnloadObject(). 30 | // 31 | // This function can only look up C function names. Other languages may have 32 | // name mangling and intrinsic language support that varies from compiler to 33 | // compiler. 34 | // 35 | // Make sure you declare your function pointers with the same calling 36 | // convention as the actual library function. Your code will crash 37 | // mysteriously if you do not do this. 38 | // 39 | // If the requested function doesn't exist, NULL is returned. 40 | // 41 | // `handle` a valid shared object handle returned by SDL_LoadObject() 42 | // `name` the name of the function to look up 43 | // returns a pointer to the function or NULL if there was an error; call 44 | // SDL_GetError() for more information. 45 | // 46 | // NOTE This function is available since SDL 2.0.0. 47 | // 48 | // See also: SDL_LoadObject 49 | // See also: SDL_UnloadObject 50 | pub fn load_function(handle voidptr, const_name &char) voidptr { 51 | return C.SDL_LoadFunction(handle, const_name) 52 | } 53 | 54 | fn C.SDL_UnloadObject(handle voidptr) 55 | 56 | // unload_object unloads a shared object from memory. 57 | // 58 | // `handle` a valid shared object handle returned by SDL_LoadObject() 59 | // 60 | // NOTE This function is available since SDL 2.0.0. 61 | // 62 | // See also: SDL_LoadFunction 63 | // See also: SDL_LoadObject 64 | pub fn unload_object(handle voidptr) { 65 | C.SDL_UnloadObject(handle) 66 | } 67 | -------------------------------------------------------------------------------- /system.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_system.h 8 | // 9 | 10 | // TODO WinRT support? 11 | /* 12 | pub enum C.SDL_WinRT_Path { 13 | } 14 | 15 | 16 | pub enum C.SDL_WinRT_DeviceFamily { 17 | } 18 | 19 | 20 | // extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType) 21 | fn C.SDL_WinRTGetFSPathUNICODE(path_type C.SDL_WinRT_Path) &C.wchar_t 22 | pub fn win_r_t_get_f_s_path_u_n_i_c_o_d_e(path_type C.SDL_WinRT_Path) &C.wchar_t{ 23 | return C.SDL_WinRTGetFSPathUNICODE(path_type) 24 | } 25 | 26 | // extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType) 27 | fn C.SDL_WinRTGetFSPathUTF8(path_type C.SDL_WinRT_Path) &char 28 | pub fn win_r_t_get_f_s_path_u_t_f8(path_type C.SDL_WinRT_Path) &char{ 29 | return C.SDL_WinRTGetFSPathUTF8(path_type) 30 | } 31 | 32 | // extern DECLSPEC SDL_WinRT_DeviceFamily SDLCALL SDL_WinRTGetDeviceFamily() 33 | fn C.SDL_WinRTGetDeviceFamily() C.SDL_WinRT_DeviceFamily 34 | pub fn win_r_t_get_device_family() C.SDL_WinRT_DeviceFamily{ 35 | return C.SDL_WinRTGetDeviceFamily() 36 | } 37 | */ 38 | 39 | fn C.SDL_IsTablet() bool 40 | 41 | // is_tablet queries if the current device is a tablet. 42 | // 43 | // If SDL can't determine this, it will return SDL_FALSE. 44 | // 45 | // returns SDL_TRUE if the device is a tablet, SDL_FALSE otherwise. 46 | // 47 | // NOTE This function is available since SDL 2.0.9. 48 | pub fn is_tablet() bool { 49 | return C.SDL_IsTablet() 50 | } 51 | 52 | // Functions used by iOS application delegates to notify SDL about state changes 53 | 54 | fn C.SDL_OnApplicationWillTerminate() 55 | pub fn on_application_will_terminate() { 56 | C.SDL_OnApplicationWillTerminate() 57 | } 58 | 59 | fn C.SDL_OnApplicationDidReceiveMemoryWarning() 60 | pub fn on_application_did_receive_memory_warning() { 61 | C.SDL_OnApplicationDidReceiveMemoryWarning() 62 | } 63 | 64 | fn C.SDL_OnApplicationWillResignActive() 65 | pub fn on_application_will_resign_active() { 66 | C.SDL_OnApplicationWillResignActive() 67 | } 68 | 69 | fn C.SDL_OnApplicationDidEnterBackground() 70 | pub fn on_application_did_enter_background() { 71 | C.SDL_OnApplicationDidEnterBackground() 72 | } 73 | 74 | fn C.SDL_OnApplicationWillEnterForeground() 75 | pub fn on_application_will_enter_foreground() { 76 | C.SDL_OnApplicationWillEnterForeground() 77 | } 78 | 79 | fn C.SDL_OnApplicationDidBecomeActive() 80 | pub fn on_application_did_become_active() { 81 | C.SDL_OnApplicationDidBecomeActive() 82 | } 83 | -------------------------------------------------------------------------------- /c/memory.c.v: -------------------------------------------------------------------------------- 1 | module c 2 | 3 | // When the Boehm collector is used, it is better to replace SDL's memory allocation functions, with versions 4 | // that Boehm will later know how to process. The callbacks here provide such versions: 5 | fn cb_malloc_func(size usize) voidptr { 6 | mut res := unsafe { nil } 7 | $if sdl_use_gc ? { 8 | res = unsafe { malloc(int(size)) } 9 | } $else { 10 | res = unsafe { C.malloc(size) } 11 | } 12 | $if trace_sdl_memory ? { 13 | C.fprintf(C.stderr, c'>> sdl.c.cb_malloc_func | size: %lu | => %p\n', size, res) 14 | } 15 | return res 16 | } 17 | 18 | fn cb_calloc_func(nmemb usize, size usize) voidptr { 19 | mut res := unsafe { nil } 20 | $if sdl_use_gc ? { 21 | res = unsafe { vcalloc(isize(nmemb) * isize(size)) } 22 | } $else { 23 | res = unsafe { C.calloc(int(nmemb), int(size)) } 24 | } 25 | $if trace_sdl_memory ? { 26 | C.fprintf(C.stderr, c'>> sdl.c.cb_calloc_func | nmemb: %lu | size: %lu | => %p\n', 27 | nmemb, size, res) 28 | } 29 | return res 30 | } 31 | 32 | fn cb_realloc_func(mem voidptr, size usize) voidptr { 33 | mut res := unsafe { nil } 34 | $if sdl_use_gc ? { 35 | res = unsafe { v_realloc(&u8(mem), isize(size)) } 36 | } $else { 37 | res = unsafe { C.realloc(&u8(mem), int(size)) } 38 | } 39 | $if trace_sdl_memory ? { 40 | C.fprintf(C.stderr, c'>> sdl.c.cb_realloc_func | mem: %p | size: %lu | => %p\n', 41 | mem, size, res) 42 | } 43 | return res 44 | } 45 | 46 | fn cb_free_func(mem voidptr) { 47 | $if trace_sdl_memory ? { 48 | C.fprintf(C.stderr, c'>> sdl.c.cb_free_func | mem: %p\n', mem) 49 | } 50 | $if sdl_use_gc ? { 51 | unsafe { free(mem) } 52 | } $else { 53 | unsafe { C.free(mem) } 54 | } 55 | } 56 | 57 | pub type MallocFunc = fn (size usize) voidptr // fn(size usize) voidptr 58 | 59 | pub type CallocFunc = fn (nmemb usize, size usize) voidptr // fn(nmemb usize, size usize) voidptr 60 | 61 | pub type ReallocFunc = fn (mem voidptr, size usize) voidptr // fn(mem voidptr, size usize) voidptr 62 | 63 | pub type FreeFunc = fn (mem voidptr) // fn(mem voidptr) 64 | 65 | fn C.SDL_SetMemoryFunctions(malloc_func MallocFunc, calloc_func CallocFunc, realloc_func ReallocFunc, free_func FreeFunc) int 66 | fn C.SDL_GetNumAllocations() int 67 | 68 | @[if !sdl_no_init ?] 69 | fn init() { 70 | prev_allocations := C.SDL_GetNumAllocations() 71 | if prev_allocations > 0 { 72 | eprintln('SDL memory allocation functions should have been replaced with the V ones, but vsdl found, that you did already ${prev_allocations} allocations.') 73 | return 74 | } 75 | replaced := C.SDL_SetMemoryFunctions(cb_malloc_func, cb_calloc_func, cb_realloc_func, 76 | cb_free_func) 77 | if replaced != 0 { 78 | eprintln('SDL memory allocation functions were not replaced.') 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /metal.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_metal.h 8 | // 9 | 10 | // A handle to a CAMetalLayer-backed NSView (macOS) or UIView (iOS/tvOS). 11 | // 12 | // NOTE This can be cast directly to an NSView or UIView. 13 | // 14 | // `typedef void *SDL_MetalView;` 15 | // C.SDL_MetalView 16 | pub type MetalView = voidptr 17 | 18 | // Metal support functions 19 | fn C.SDL_Metal_CreateView(window &C.SDL_Window) MetalView 20 | 21 | // metal_create_view creates a CAMetalLayer-backed NSView/UIView and attach it to the specified 22 | // window. 23 | // 24 | // On macOS, this does *not* associate a MTLDevice with the CAMetalLayer on 25 | // its own. It is up to user code to do that. 26 | // 27 | // The returned handle can be casted directly to a NSView or UIView. To access 28 | // the backing CAMetalLayer, call SDL_Metal_GetLayer(). 29 | // 30 | // NOTE This function is available since SDL 2.0.12. 31 | // 32 | // See also: SDL_Metal_DestroyView 33 | // See also: SDL_Metal_GetLayer 34 | pub fn metal_create_view(window &Window) MetalView { 35 | return MetalView(voidptr(C.SDL_Metal_CreateView(window))) 36 | } 37 | 38 | fn C.SDL_Metal_DestroyView(view C.SDL_MetalView) 39 | 40 | // metal_destroy_view destroys an existing SDL_MetalView object. 41 | // 42 | // This should be called before SDL_DestroyWindow, if SDL_Metal_CreateView was 43 | // called after SDL_CreateWindow. 44 | // 45 | // NOTE This function is available since SDL 2.0.12. 46 | // 47 | // See also: SDL_Metal_CreateView 48 | pub fn metal_destroy_view(view MetalView) { 49 | C.SDL_Metal_DestroyView(voidptr(view)) 50 | } 51 | 52 | fn C.SDL_Metal_GetLayer(view C.SDL_MetalView) voidptr 53 | 54 | // metal_get_layer gets a pointer to the backing CAMetalLayer for the given view. 55 | // 56 | // NOTE This function is available since SDL 2.0.14. 57 | // 58 | // See also: SDL_MetalCreateView 59 | pub fn metal_get_layer(view MetalView) voidptr { 60 | return C.SDL_Metal_GetLayer(voidptr(view)) 61 | } 62 | 63 | fn C.SDL_Metal_GetDrawableSize(window &C.SDL_Window, w &int, h &int) 64 | 65 | // metal_get_drawable_size gets the size of a window's underlying drawable in pixels (for use with 66 | // setting viewport, scissor & etc). 67 | // 68 | // `window` SDL_Window from which the drawable size should be queried 69 | // `w` Pointer to variable for storing the width in pixels, may be NULL 70 | // `h` Pointer to variable for storing the height in pixels, may be NULL 71 | // 72 | // NOTE This function is available since SDL 2.0.14. 73 | // 74 | // See also: SDL_GetWindowSize 75 | // See also: SDL_CreateWindow 76 | pub fn metal_get_drawable_size(window &Window, w &int, h &int) { 77 | C.SDL_Metal_GetDrawableSize(window, w, h) 78 | } 79 | -------------------------------------------------------------------------------- /locale.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_locale.h 8 | // 9 | 10 | @[typedef] 11 | pub struct C.SDL_Locale { 12 | pub: 13 | language &char // const, A language name, like "en" for English. 14 | country &char // const, A country, like "US" for America. Can be NULL. 15 | } 16 | 17 | pub type Locale = C.SDL_Locale 18 | 19 | fn C.SDL_GetPreferredLocales() &C.SDL_Locale 20 | 21 | // get_preferred_locales reports the user's preferred locale. 22 | // 23 | // This returns an array of SDL_Locale structs, the final item zeroed out. 24 | // When the caller is done with this array, it should call SDL_free() on the 25 | // returned value; all the memory involved is allocated in a single block, so 26 | // a single SDL_free() will suffice. 27 | // 28 | // Returned language strings are in the format xx, where 'xx' is an ISO-639 29 | // language specifier (such as "en" for English, "de" for German, etc). 30 | // Country strings are in the format YY, where "YY" is an ISO-3166 country 31 | // code (such as "US" for the United States, "CA" for Canada, etc). Country 32 | // might be NULL if there's no specific guidance on them (so you might get { 33 | // "en", "US" } for American English, but { "en", NULL } means "English 34 | // language, generically"). Language strings are never NULL, except to 35 | // terminate the array. 36 | // 37 | // Please note that not all of these strings are 2 characters; some are three 38 | // or more. 39 | // 40 | // The returned list of locales are in the order of the user's preference. For 41 | // example, a German citizen that is fluent in US English and knows enough 42 | // Japanese to navigate around Tokyo might have a list like: { "de", "en_US", 43 | // "jp", NULL }. Someone from England might prefer British English (where 44 | // "color" is spelled "colour", etc), but will settle for anything like it: { 45 | // "en_GB", "en", NULL }. 46 | // 47 | // This function returns NULL on error, including when the platform does not 48 | // supply this information at all. 49 | // 50 | // This might be a "slow" call that has to query the operating system. It's 51 | // best to ask for this once and save the results. However, this list can 52 | // change, usually because the user has changed a system preference outside of 53 | // your program; SDL will send an SDL_LOCALECHANGED event in this case, if 54 | // possible, and you can call this function again to get an updated copy of 55 | // preferred locales. 56 | // 57 | // returns array of locales, terminated with a locale with a NULL language 58 | // field. Will return NULL on error. 59 | // 60 | // NOTE This function is available since SDL 2.0.14. 61 | pub fn get_preferred_locales() &Locale { 62 | return C.SDL_GetPreferredLocales() 63 | } 64 | -------------------------------------------------------------------------------- /gesture.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_gesture.h 8 | // 9 | 10 | // `typedef Sint64 SDL_GestureID;` 11 | // GestureID can be cast to C.SDL_GestureID 12 | pub type GestureID = i64 13 | 14 | fn C.SDL_RecordGesture(touch_id C.SDL_TouchID) int 15 | 16 | // record_gesture begins recording a gesture on a specified touch device or all touch devices. 17 | // 18 | // If the parameter `touchId` is -1 (i.e., all devices), this function will 19 | // always return 1, regardless of whether there actually are any devices. 20 | // 21 | // `touchId` the touch device id, or -1 for all touch devices 22 | // returns 1 on success or 0 if the specified device could not be found. 23 | // 24 | // NOTE This function is available since SDL 2.0.0. 25 | // 26 | // See also: SDL_GetTouchDevice 27 | pub fn record_gesture(touch_id TouchID) int { 28 | return C.SDL_RecordGesture(C.SDL_TouchID(touch_id)) 29 | } 30 | 31 | fn C.SDL_SaveAllDollarTemplates(dst &C.SDL_RWops) int 32 | 33 | // save_all_dollar_templates saves all currently loaded Dollar Gesture templates. 34 | // 35 | // `dst` a SDL_RWops to save to 36 | // returns the number of saved templates on success or 0 on failure; call 37 | // SDL_GetError() for more information. 38 | // 39 | // NOTE This function is available since SDL 2.0.0. 40 | // 41 | // See also: SDL_LoadDollarTemplates 42 | // See also: SDL_SaveDollarTemplate 43 | pub fn save_all_dollar_templates(dst &RWops) int { 44 | return C.SDL_SaveAllDollarTemplates(dst) 45 | } 46 | 47 | fn C.SDL_SaveDollarTemplate(gesture_id C.SDL_GestureID, dst &C.SDL_RWops) int 48 | 49 | // save_dollar_template saves a currently loaded Dollar Gesture template. 50 | // 51 | // `gestureId` a gesture id 52 | // `dst` a SDL_RWops to save to 53 | // returns 1 on success or 0 on failure; call SDL_GetError() for more 54 | // information. 55 | // 56 | // NOTE This function is available since SDL 2.0.0. 57 | // 58 | // See also: SDL_LoadDollarTemplates 59 | // See also: SDL_SaveAllDollarTemplates 60 | pub fn save_dollar_template(gesture_id GestureID, dst &RWops) int { 61 | return C.SDL_SaveDollarTemplate(C.SDL_GestureID(gesture_id), dst) 62 | } 63 | 64 | fn C.SDL_LoadDollarTemplates(touch_id C.SDL_TouchID, src &C.SDL_RWops) int 65 | 66 | // load_dollar_templates loads Dollar Gesture templates from a file. 67 | // 68 | // `touchId` a touch id 69 | // `src` a SDL_RWops to load from 70 | // returns the number of loaded templates on success or a negative error code 71 | // (or 0) on failure; call SDL_GetError() for more information. 72 | // 73 | // NOTE This function is available since SDL 2.0.0. 74 | // 75 | // See also: SDL_SaveAllDollarTemplates 76 | // See also: SDL_SaveDollarTemplate 77 | pub fn load_dollar_templates(touch_id TouchID, src &RWops) int { 78 | return C.SDL_LoadDollarTemplates(C.SDL_TouchID(touch_id), src) 79 | } 80 | -------------------------------------------------------------------------------- /main_windows.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_main.h 8 | // 9 | 10 | fn C.SDL_RegisterApp(name &char, style u32, h_inst voidptr) int 11 | 12 | // register_app registers a win32 window class for SDL's use. 13 | // 14 | // This can be called to set the application window class at startup. It is 15 | // safe to call this multiple times, as long as every call is eventually 16 | // paired with a call to SDL_UnregisterApp, but a second registration attempt 17 | // while a previous registration is still active will be ignored, other than 18 | // to increment a counter. 19 | // 20 | // Most applications do not need to, and should not, call this directly; SDL 21 | // will call it when initializing the video subsystem. 22 | // 23 | // `name` the window class name, in UTF-8 encoding. If NULL, SDL 24 | // currently uses "SDL_app" but this isn't guaranteed. 25 | // `style` the value to use in WNDCLASSEX::style. If `name` is NULL, SDL 26 | // currently uses `(CS_BYTEALIGNCLIENT | CS_OWNDC)` regardless of 27 | // what is specified here. 28 | // `hInst` the HINSTANCE to use in WNDCLASSEX::hInstance. If zero, SDL 29 | // will use `GetModuleHandle(NULL)` instead. 30 | // returns 0 on success, -1 on error. SDL_GetError() may have details. 31 | // 32 | // NOTE This function is available since SDL 2.0.2. 33 | pub fn register_app(name &char, style u32, h_inst voidptr) int { 34 | return C.SDL_RegisterApp(name, style, h_inst) 35 | } 36 | 37 | fn C.SDL_UnregisterApp() 38 | 39 | // unregister_app deregisters the win32 window class from an SDL_RegisterApp call. 40 | // 41 | // This can be called to undo the effects of SDL_RegisterApp. 42 | // 43 | // Most applications do not need to, and should not, call this directly; SDL 44 | // will call it when deinitializing the video subsystem. 45 | // 46 | // It is safe to call this multiple times, as long as every call is eventually 47 | // paired with a prior call to SDL_RegisterApp. The window class will only be 48 | // deregistered when the registration counter in SDL_RegisterApp decrements to 49 | // zero through calls to this function. 50 | // 51 | // NOTE This function is available since SDL 2.0.2. 52 | pub fn unregister_app() { 53 | C.SDL_UnregisterApp() 54 | } 55 | 56 | /* 57 | TODO support GDK? 58 | $if gdk ? { 59 | fn C.SDL_GDKRunApp(main_function C.SDL_main_func, reserved voidptr) int 60 | // Initialize and launch an SDL GDK application. 61 | // 62 | // `main_function` the SDL app's C-style main(), an SDL_main_func 63 | // `reserved` reserved for future use; should be NULL 64 | // returns 0 on success or -1 on failure; call SDL_GetError() to retrieve 65 | // more information on the failure. 66 | // 67 | // NOTE This function is available since SDL 2.24.0. 68 | gdk_run_app(main_function C.SDL_main_func, reserved voidptr) int { 69 | return C.SDL_GDKRunApp(main_function, reserved) 70 | } 71 | } 72 | */ 73 | -------------------------------------------------------------------------------- /system_ios.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_system.h 8 | // 9 | 10 | // Platform specific functions for iOS 11 | 12 | pub type IOSAnimationCallback = fn (params voidptr) 13 | 14 | fn C.SDL_iOSSetAnimationCallback(window &C.SDL_Window, interval int, callback IOSAnimationCallback, callbackParam voidptr) int 15 | pub fn ios_set_animation_callback(window &Window, interval int, callback IOSAnimationCallback, callback_param voidptr) int { 16 | return C.SDL_iOSSetAnimationCallback(window, interval, callback, callback_param) 17 | } 18 | 19 | fn C.SDL_iPhoneSetAnimationCallback(window &C.SDL_Window, interval int, callback IOSAnimationCallback, callback_param voidptr) int 20 | 21 | // iphone_set_animation_callback sets the animation callback on Apple iOS. 22 | // 23 | // The function prototype for `callback` is: 24 | // 25 | // ```c 26 | // void callback(void* callbackParam); 27 | // ``` 28 | // 29 | // Where its parameter, `callbackParam`, is what was passed as `callbackParam` 30 | // to SDL_iPhoneSetAnimationCallback(). 31 | // 32 | // This function is only available on Apple iOS. 33 | // 34 | // For more information see: 35 | // https://github.com/libsdl-org/SDL/blob/main/docs/README-ios.md 36 | // 37 | // This functions is also accessible using the macro 38 | // SDL_iOSSetAnimationCallback() since SDL 2.0.4. 39 | // 40 | // `window` the window for which the animation callback should be set 41 | // `interval` the number of frames after which **callback** will be 42 | // called 43 | // `callback` the function to call for every frame. 44 | // `callbackParam` a pointer that is passed to `callback`. 45 | // returns 0 on success or a negative error code on failure; call 46 | // SDL_GetError() for more information. 47 | // 48 | // NOTE This function is available since SDL 2.0.0. 49 | // 50 | // See also: SDL_iPhoneSetEventPump 51 | pub fn iphone_set_animation_callback(window &Window, interval int, callback IOSAnimationCallback, callback_param voidptr) int { 52 | return C.SDL_iPhoneSetAnimationCallback(window, interval, callback, callback_param) 53 | } 54 | 55 | fn C.SDL_iOSSetEventPump(enabled) 56 | pub fn ios_set_event_pump(enabled bool) { 57 | C.SDL_iOSSetEventPump(enabled) 58 | } 59 | 60 | fn C.SDL_iPhoneSetEventPump(enabled bool) 61 | 62 | // iphone_set_event_pump uses this function to enable or disable the SDL event pump on Apple iOS. 63 | // 64 | // This function is only available on Apple iOS. 65 | // 66 | // This functions is also accessible using the macro SDL_iOSSetEventPump() 67 | // since SDL 2.0.4. 68 | // 69 | // `enabled` SDL_TRUE to enable the event pump, SDL_FALSE to disable it 70 | // 71 | // NOTE This function is available since SDL 2.0.0. 72 | // 73 | // See also: SDL_iPhoneSetAnimationCallback 74 | pub fn iphone_set_event_pump(enabled bool) { 75 | C.SDL_iPhoneSetEventPump(enabled) 76 | } 77 | 78 | fn C.SDL_OnApplicationDidChangeStatusBarOrientation() 79 | pub fn on_application_did_change_status_bar_orientation() { 80 | C.SDL_OnApplicationDidChangeStatusBarOrientation() 81 | } 82 | -------------------------------------------------------------------------------- /error.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_error.h 8 | // 9 | 10 | // Skipped: 11 | /* 12 | extern DECLSPEC int SDLCALL SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); 13 | */ 14 | fn C.SDL_GetError() &char 15 | 16 | // get_error retrieves a message about the last error that occurred on the current 17 | // thread. 18 | // 19 | // It is possible for multiple errors to occur before calling SDL_GetError(). 20 | // Only the last error is returned. 21 | // 22 | // The message is only applicable when an SDL function has signaled an error. 23 | // You must check the return values of SDL function calls to determine when to 24 | // appropriately call SDL_GetError(). You should *not* use the results of 25 | // SDL_GetError() to decide if an error has occurred! Sometimes SDL will set 26 | // an error string even when reporting success. 27 | // 28 | // SDL will *not* clear the error string for successful API calls. You *must* 29 | // check return values for failure cases before you can assume the error 30 | // string applies. 31 | // 32 | // Error strings are set per-thread, so an error set in a different thread 33 | // will not interfere with the current thread's operation. 34 | // 35 | // The returned string is internally allocated and must not be freed by the 36 | // application. 37 | // 38 | // returns a message with information about the specific error that occurred, 39 | // or an empty string if there hasn't been an error message set since 40 | // the last call to SDL_ClearError(). The message is only applicable 41 | // when an SDL function has signaled an error. You must check the 42 | // return values of SDL function calls to determine when to 43 | // appropriately call SDL_GetError(). 44 | // 45 | // NOTE This function is available since SDL 2.0.0. 46 | // 47 | // See also: SDL_ClearError 48 | // See also: SDL_SetError 49 | pub fn get_error() &char { 50 | return C.SDL_GetError() 51 | } 52 | 53 | fn C.SDL_GetErrorMsg(errstr &char, maxlen int) &char 54 | 55 | // get_error_msg gets the last error message that was set for the current thread. 56 | // 57 | // This allows the caller to copy the error string into a provided buffer, but 58 | // otherwise operates exactly the same as SDL_GetError(). 59 | // 60 | // `errstr` A buffer to fill with the last error message that was set for 61 | // the current thread 62 | // `maxlen` The size of the buffer pointed to by the errstr parameter 63 | // returns the pointer passed in as the `errstr` parameter. 64 | // 65 | // NOTE This function is available since SDL 2.0.14. 66 | // 67 | // See also: SDL_GetError 68 | pub fn get_error_msg(errstr &char, maxlen int) &char { 69 | return C.SDL_GetErrorMsg(errstr, maxlen) 70 | } 71 | 72 | fn C.SDL_ClearError() 73 | 74 | // clear_error clears any previous error message for this thread. 75 | // 76 | // NOTE This function is available since SDL 2.0.0. 77 | // 78 | // See also: SDL_GetError 79 | // See also: SDL_SetError 80 | pub fn clear_error() { 81 | C.SDL_ClearError() 82 | } 83 | 84 | // ErrorCode is C.SDL_errorcode 85 | pub enum ErrorCode { 86 | enomem = C.SDL_ENOMEM 87 | efread = C.SDL_EFREAD 88 | efwrite = C.SDL_EFWRITE 89 | efseek = C.SDL_EFSEEK 90 | unsupported = C.SDL_UNSUPPORTED 91 | lasterror = C.SDL_LASTERROR 92 | } 93 | 94 | fn C.SDL_Error(code C.SDL_errorcode) int 95 | 96 | // error SDL_Error() unconditionally returns -1. 97 | pub fn error(code ErrorCode) int { 98 | return C.SDL_Error(C.SDL_errorcode(code)) 99 | } 100 | -------------------------------------------------------------------------------- /clipboard.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_clipboard.h 8 | // 9 | 10 | fn C.SDL_SetClipboardText(text &char) int 11 | 12 | // set_clipboard_text puts UTF-8 text into the clipboard. 13 | // 14 | // `text` the text to store in the clipboard 15 | // returns 0 on success or a negative error code on failure; call 16 | // SDL_GetError() for more information. 17 | // 18 | // NOTE This function is available since SDL 2.0.0. 19 | // 20 | // See also: SDL_GetClipboardText 21 | // See also: SDL_HasClipboardText 22 | pub fn set_clipboard_text(text &char) int { 23 | return C.SDL_SetClipboardText(text) 24 | } 25 | 26 | fn C.SDL_GetClipboardText() &char 27 | 28 | // get_clipboard_text gets UTF-8 text from the clipboard, which must be freed with SDL_free(). 29 | // 30 | // This functions returns empty string if there was not enough memory left for 31 | // a copy of the clipboard's content. 32 | // 33 | // returns the clipboard text on success or an empty string on failure; call 34 | // SDL_GetError() for more information. Caller must call SDL_free() 35 | // on the returned pointer when done with it (even if there was an 36 | // error). 37 | // 38 | // NOTE This function is available since SDL 2.0.0. 39 | // 40 | // See also: SDL_HasClipboardText 41 | // See also: SDL_SetClipboardText 42 | pub fn get_clipboard_text() &char { 43 | return C.SDL_GetClipboardText() 44 | } 45 | 46 | fn C.SDL_HasClipboardText() bool 47 | 48 | // has_clipboard_text queries whether the clipboard exists and contains a non-empty text string. 49 | // 50 | // returns SDL_TRUE if the clipboard has text, or SDL_FALSE if it does not. 51 | // 52 | // NOTE This function is available since SDL 2.0.0. 53 | // 54 | // See also: SDL_GetClipboardText 55 | // See also: SDL_SetClipboardText 56 | pub fn has_clipboard_text() bool { 57 | return C.SDL_HasClipboardText() 58 | } 59 | 60 | fn C.SDL_SetPrimarySelectionText(const_text &char) int 61 | 62 | // set_primary_selection_text puts UTF-8 text into the primary selection. 63 | // 64 | // `text` the text to store in the primary selection 65 | // returns 0 on success or a negative error code on failure; call 66 | // SDL_GetError() for more information. 67 | // 68 | // NOTE This function is available since SDL 2.26.0. 69 | // 70 | // See also: SDL_GetPrimarySelectionText 71 | // See also: SDL_HasPrimarySelectionText 72 | pub fn set_primary_selection_text(const_text &char) int { 73 | return C.SDL_SetPrimarySelectionText(const_text) 74 | } 75 | 76 | fn C.SDL_GetPrimarySelectionText() &char 77 | 78 | // get_primary_selection_text gets UTF-8 text from the primary selection, which must be freed with 79 | // SDL_free(). 80 | // 81 | // This functions returns empty string if there was not enough memory left for 82 | // a copy of the primary selection's content. 83 | // 84 | // returns the primary selection text on success or an empty string on 85 | // failure; call SDL_GetError() for more information. Caller must 86 | // call SDL_free() on the returned pointer when done with it (even if 87 | // there was an error). 88 | // 89 | // NOTE This function is available since SDL 2.26.0. 90 | // 91 | // See also: SDL_HasPrimarySelectionText 92 | // See also: SDL_SetPrimarySelectionText 93 | pub fn get_primary_selection_text() &char { 94 | return C.SDL_GetPrimarySelectionText() 95 | } 96 | 97 | fn C.SDL_HasPrimarySelectionText() bool 98 | 99 | // has_primary_selection_text querys whether the primary selection exists and contains a non-empty text 100 | // string. 101 | // 102 | // returns SDL_TRUE if the primary selection has text, or SDL_FALSE if it 103 | // does not. 104 | // 105 | // NOTE This function is available since SDL 2.26.0. 106 | // 107 | // See also: SDL_GetPrimarySelectionText 108 | // See also: SDL_SetPrimarySelectionText 109 | pub fn has_primary_selection_text() bool { 110 | return C.SDL_HasPrimarySelectionText() 111 | } 112 | -------------------------------------------------------------------------------- /touch.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_touch.h 8 | // 9 | 10 | // `typedef Sint64 SDL_TouchID;` 11 | pub type TouchID = i64 12 | 13 | // `typedef Sint64 SDL_FingerID;` 14 | pub type FingerID = i64 15 | 16 | // Used as the device ID for mouse events simulated with touch input 17 | pub const touch_mouseid = C.SDL_TOUCH_MOUSEID // ((Uint32)-1) 18 | 19 | // Used as the SDL_TouchID for touch events simulated with mouse input 20 | pub const mouse_touch_id = C.SDL_MOUSE_TOUCHID // ((Sint64)-1) 21 | 22 | // TouchDeviceType is C.SDL_TouchDeviceType 23 | pub enum TouchDeviceType { 24 | invalid = C.SDL_TOUCH_DEVICE_INVALID // -1 25 | direct = C.SDL_TOUCH_DEVICE_DIRECT // touch screen with window-relative coordinates 26 | indirect_absolute = C.SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE // trackpad with absolute device coordinates 27 | indirect_relative = C.SDL_TOUCH_DEVICE_INDIRECT_RELATIVE // trackpad with screen cursor-relative coordinates 28 | } 29 | 30 | @[typedef] 31 | pub struct C.SDL_Finger { 32 | pub: 33 | id FingerID // C.SDL_FingerID 34 | x f32 35 | y f32 36 | pressure f32 37 | } 38 | 39 | pub type Finger = C.SDL_Finger 40 | 41 | fn C.SDL_GetNumTouchDevices() int 42 | 43 | // get_num_touch_devices gets the number of registered touch devices. 44 | // 45 | // On some platforms SDL first sees the touch device if it was actually used. 46 | // Therefore SDL_GetNumTouchDevices() may return 0 although devices are 47 | // available. After using all devices at least once the number will be 48 | // correct. 49 | // 50 | // This was fixed for Android in SDL 2.0.1. 51 | // 52 | // returns the number of registered touch devices. 53 | // 54 | // NOTE This function is available since SDL 2.0.0. 55 | // 56 | // See also: SDL_GetTouchDevice 57 | pub fn get_num_touch_devices() int { 58 | return C.SDL_GetNumTouchDevices() 59 | } 60 | 61 | fn C.SDL_GetTouchDevice(index int) TouchID 62 | 63 | // C.SDL_TouchID 64 | 65 | // get_touch_device gets the touch ID with the given index. 66 | // 67 | // `index` the touch device index 68 | // returns the touch ID with the given index on success or 0 if the index is 69 | // invalid; call SDL_GetError() for more information. 70 | // 71 | // NOTE This function is available since SDL 2.0.0. 72 | // 73 | // See also: SDL_GetNumTouchDevices 74 | pub fn get_touch_device(index int) TouchID { 75 | return C.SDL_GetTouchDevice(index) 76 | } 77 | 78 | fn C.SDL_GetTouchName(index int) &char 79 | 80 | // get_touch_name gets the touch device name as reported from the driver or NULL if the index 81 | // is invalid. 82 | // 83 | // NOTE This function is available since SDL 2.0.22. 84 | pub fn get_touch_name(index int) &char { 85 | return C.SDL_GetTouchName(index) 86 | } 87 | 88 | fn C.SDL_GetTouchDeviceType(touch_id TouchID) TouchDeviceType 89 | 90 | // get_touch_device_type gets the type of the given touch device. 91 | // 92 | // NOTE This function is available since SDL 2.0.10. 93 | pub fn get_touch_device_type(touch_id TouchID) TouchDeviceType { 94 | return unsafe { TouchDeviceType(int(C.SDL_GetTouchDeviceType(touch_id))) } 95 | } 96 | 97 | fn C.SDL_GetNumTouchFingers(touch_id TouchID) int 98 | 99 | // get_num_touch_fingers gets the number of active fingers for a given touch device. 100 | // 101 | // `touchID` the ID of a touch device 102 | // returns the number of active fingers for a given touch device on success 103 | // or 0 on failure; call SDL_GetError() for more information. 104 | // 105 | // NOTE This function is available since SDL 2.0.0. 106 | // 107 | // See also: SDL_GetTouchFinger 108 | pub fn get_num_touch_fingers(touch_id TouchID) int { 109 | return C.SDL_GetNumTouchFingers(touch_id) 110 | } 111 | 112 | fn C.SDL_GetTouchFinger(touch_id TouchID, index int) &C.SDL_Finger 113 | 114 | // get_touch_finger gets the finger object for specified touch device ID and finger index. 115 | // 116 | // The returned resource is owned by SDL and should not be deallocated. 117 | // 118 | // `touchID` the ID of the requested touch device 119 | // `index` the index of the requested finger 120 | // returns a pointer to the SDL_Finger object or NULL if no object at the 121 | // given ID and index could be found. 122 | // 123 | // NOTE This function is available since SDL 2.0.0. 124 | // 125 | // See also: SDL_RecordGesture 126 | pub fn get_touch_finger(touch_id TouchID, index int) &Finger { 127 | return C.SDL_GetTouchFinger(touch_id, index) 128 | } 129 | -------------------------------------------------------------------------------- /examples/basic_image/basic_image.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2022 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | // 5 | // Creates a window through SDL2 and load all test images into memory, 6 | // and display them in a grid. 7 | // If an image can not be loaded it may be because the host platform's 8 | // SDL2_image library is not compiled with support for the specific 9 | // image format. A successful test should show 5 images. 10 | module main 11 | 12 | import os 13 | import sdl 14 | import sdl.image 15 | 16 | const images = ['v-logo.svg', 'v-logo.png', 'v-logo.jpg', 'v-logo.lossless.webp', 'v-logo.webp'] 17 | 18 | fn get_asset_path(path string) string { 19 | $if android { 20 | return os.join_path('images', path) 21 | } $else { 22 | return os.resource_abs_path(os.join_path('..', 'assets', 'images', path)) 23 | } 24 | } 25 | 26 | fn load_image(path string) !&sdl.Surface { 27 | asset_path := get_asset_path(path) 28 | rw := sdl.rw_from_file(asset_path.str, 'rb'.str) 29 | if rw == sdl.null { 30 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 31 | return error('Could not load image "${path}" RW from mem data: ${error_msg}') 32 | } 33 | img := image.load_rw(rw, 1) 34 | if img == sdl.null { 35 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 36 | return error('Could not load image RW "${path}" data: ${error_msg}') 37 | } 38 | return img 39 | } 40 | 41 | fn main() { 42 | println('Const version ${image.major_version}.${image.minor_version}.${image.patchlevel}') 43 | mut compiled_version := sdl.Version{} 44 | C.SDL_IMAGE_VERSION(&compiled_version) 45 | println('Compiled against version ${compiled_version.str()}') 46 | linked_version := image.linked_version() 47 | println('Runtime loaded version ${linked_version.major}.${linked_version.minor}.${linked_version.patch}') 48 | 49 | $if debug ? { 50 | // SDL debug info, must be called before sdl.init 51 | sdl.log_set_all_priority(sdl.LogPriority.verbose) 52 | } 53 | sdl.init(sdl.init_video) 54 | window := sdl.create_window('Hello SDL2_image'.str, 300, 300, 500, 300, 0) 55 | renderer := sdl.create_renderer(window, -1, u32(sdl.RendererFlags.accelerated) | u32(sdl.RendererFlags.presentvsync)) 56 | 57 | flags := int(image.InitFlags.png) 58 | 59 | image_init_result := image.init(flags) 60 | if (image_init_result & flags) != flags { 61 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 62 | panic('Could not initialize SDL2_image: ${error_msg}') 63 | } 64 | 65 | // Hint the render, before creating textures, that we want 66 | // as high a scale quality as possible. This improves the 67 | // view quality of most textures when they are scaled down. 68 | sdl.set_hint(sdl.hint_render_scale_quality.str, '2'.str) 69 | 70 | mut image_textures := []&sdl.Texture{} 71 | for image in images { 72 | surface := load_image(image) or { 73 | eprintln('Loading of image ${image} failed: ${err.msg()}') 74 | // No panic or exit here. This way the example also 75 | // serves as a visual test, of what SDL2_image *can* load 76 | // on this platform. 77 | continue 78 | } 79 | image_textures << sdl.create_texture_from_surface(renderer, surface) 80 | } 81 | 82 | mut should_close := false 83 | for { 84 | evt := sdl.Event{} 85 | for 0 < sdl.poll_event(&evt) { 86 | match evt.@type { 87 | .quit { 88 | should_close = true 89 | } 90 | .keydown { 91 | key := unsafe { sdl.KeyCode(evt.key.keysym.sym) } 92 | match key { 93 | .escape { 94 | should_close = true 95 | } 96 | else {} 97 | } 98 | } 99 | else {} 100 | } 101 | } 102 | if should_close { 103 | break 104 | } 105 | 106 | sdl.set_render_draw_color(renderer, 255, 255, 255, 255) 107 | sdl.render_clear(renderer) 108 | 109 | mut win_w := 0 110 | sdl.get_window_size(window, win_w, sdl.null) 111 | 112 | // Render images in a grid 113 | pad := 20 // Padding between each image 114 | render_dim := 100 // Render the image texture as size "dim x dim" 115 | cols := int(win_w / (20 + render_dim)) 116 | mut y := pad 117 | mut x := pad 118 | mut col := 0 119 | for texture in image_textures { 120 | x = pad + (col * (pad + render_dim)) 121 | if x + render_dim > win_w { 122 | x = pad 123 | y += pad + render_dim 124 | } 125 | mut dstrect := sdl.Rect{x, y, render_dim, render_dim} 126 | sdl.render_copy(renderer, texture, sdl.null, &dstrect) 127 | 128 | col++ 129 | if col > cols { 130 | col = 1 131 | } 132 | } 133 | 134 | sdl.render_present(renderer) 135 | } 136 | 137 | for texture in image_textures { 138 | if !isnil(texture) { 139 | sdl.destroy_texture(texture) 140 | } 141 | } 142 | 143 | sdl.destroy_renderer(renderer) 144 | sdl.destroy_window(window) 145 | sdl.quit() 146 | } 147 | -------------------------------------------------------------------------------- /filesystem.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_filesystem.h 8 | // 9 | 10 | fn C.SDL_GetBasePath() &char 11 | 12 | // get_base_path gets the directory where the application was run from. 13 | // 14 | // This is not necessarily a fast call, so you should call this once near 15 | // startup and save the string if you need it. 16 | // 17 | // **Mac OS X and iOS Specific Functionality**: If the application is in a 18 | // ".app" bundle, this function returns the Resource directory (e.g. 19 | // MyApp.app/Contents/Resources/). This behaviour can be overridden by adding 20 | // a property to the Info.plist file. Adding a string key with the name 21 | // SDL_FILESYSTEM_BASE_DIR_TYPE with a supported value will change the 22 | // behaviour. 23 | // 24 | // Supported values for the SDL_FILESYSTEM_BASE_DIR_TYPE property (Given an 25 | // application in /Applications/SDLApp/MyApp.app): 26 | // 27 | // - `resource`: bundle resource directory (the default). For example: 28 | // `/Applications/SDLApp/MyApp.app/Contents/Resources` 29 | // - `bundle`: the Bundle directory. For example: 30 | // `/Applications/SDLApp/MyApp.app/` 31 | // - `parent`: the containing directory of the bundle. For example: 32 | // `/Applications/SDLApp/` 33 | // 34 | // **Nintendo 3DS Specific Functionality**: This function returns "romfs" 35 | // directory of the application as it is uncommon to store resources outside 36 | // the executable. As such it is not a writable directory. 37 | // 38 | // The returned path is guaranteed to end with a path separator ('\\' on 39 | // Windows, '/' on most other platforms). 40 | // 41 | // The pointer returned is owned by the caller. Please call SDL_free() on the 42 | // pointer when done with it. 43 | // 44 | // returns an absolute path in UTF-8 encoding to the application data 45 | // directory. NULL will be returned on error or when the platform 46 | // doesn't implement this functionality, call SDL_GetError() for more 47 | // information. 48 | // 49 | // NOTE This function is available since SDL 2.0.1. 50 | // 51 | // See also: SDL_GetPrefPath 52 | pub fn get_base_path() &char { 53 | return C.SDL_GetBasePath() 54 | } 55 | 56 | fn C.SDL_GetPrefPath(const_org &char, const_app &char) &char 57 | 58 | // get_pref_path gets the user-and-app-specific path where files can be written. 59 | // 60 | // Get the "pref dir". This is meant to be where users can write personal 61 | // files (preferences and save games, etc) that are specific to your 62 | // application. This directory is unique per user, per application. 63 | // 64 | // This function will decide the appropriate location in the native 65 | // filesystem, create the directory if necessary, and return a string of the 66 | // absolute path to the directory in UTF-8 encoding. 67 | // 68 | // On Windows, the string might look like: 69 | // 70 | // `C:\\Users\\bob\\AppData\\Roaming\\My Company\\My Program Name\\` 71 | // 72 | // On Linux, the string might look like: 73 | // 74 | // `/home/bob/.local/share/My Program Name/` 75 | // 76 | // On Mac OS X, the string might look like: 77 | // 78 | // `/Users/bob/Library/Application Support/My Program Name/` 79 | // 80 | // You should assume the path returned by this function is the only safe place 81 | // to write files (and that SDL_GetBasePath(), while it might be writable, or 82 | // even the parent of the returned path, isn't where you should be writing 83 | // things). 84 | // 85 | // Both the org and app strings may become part of a directory name, so please 86 | // follow these rules: 87 | // 88 | // - Try to use the same org string (_including case-sensitivity_) for all 89 | // your applications that use this function. 90 | // - Always use a unique app string for each one, and make sure it never 91 | // changes for an app once you've decided on it. 92 | // - Unicode characters are legal, as long as it's UTF-8 encoded, but... 93 | // - ...only use letters, numbers, and spaces. Avoid punctuation like "Game 94 | // Name 2: Bad Guy's Revenge!" ... "Game Name 2" is sufficient. 95 | // 96 | // The returned path is guaranteed to end with a path separator ('\\' on 97 | // Windows, '/' on most other platforms). 98 | // 99 | // The pointer returned is owned by the caller. Please call SDL_free() on the 100 | // pointer when done with it. 101 | // 102 | // `org` the name of your organization 103 | // `app` the name of your application 104 | // returns a UTF-8 string of the user directory in platform-dependent 105 | // notation. NULL if there's a problem (creating directory failed, 106 | // etc.). 107 | // 108 | // NOTE This function is available since SDL 2.0.1. 109 | // 110 | // See also: SDL_GetBasePath 111 | pub fn get_pref_path(const_org &char, const_app &char) &char { 112 | return C.SDL_GetPrefPath(const_org, const_app) 113 | } 114 | -------------------------------------------------------------------------------- /examples/lbm/cell.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import math 4 | import rand 5 | 6 | // This file contains Code and data structures for a Lattice-Boltzmann-Method (LBM) 7 | // fluid flow simulation. The simulation is 2 Dimension, with 9 possible directions (D2Q9) 8 | // 9 | // 8 1 2 10 | // 11 | // 7 0 3 12 | // 13 | // 6 5 4 14 | 15 | // Vi is an enum for direction vector of D2Q9 Lattice. 16 | pub enum Vi { 17 | center = 0 18 | north = 1 19 | north_east = 2 20 | // 21 | east = 3 22 | south_east = 4 23 | south = 5 24 | // 25 | south_west = 6 26 | west = 7 27 | north_west = 8 28 | } 29 | 30 | // vfmt off 31 | const opp = [ 32 | Vi.center, Vi.south, Vi.south_west, 33 | Vi.west, Vi.north_west, Vi.north, 34 | Vi.north_east, Vi.east, Vi.south_east, 35 | ]! 36 | 37 | // Array defined here in order to loop over a Vi enum. 38 | // Warning: This array must be coherent with Vi enum order ! 39 | const vi = [ 40 | Vi.center, Vi.north, Vi.north_east, 41 | Vi.east, Vi.south_east, Vi.south, 42 | Vi.south_west, Vi.west, Vi.north_west, 43 | ]! 44 | 45 | // wi is the weight of mini-cells. 46 | // Warning: This array must be coherent with Vi enum order ! 47 | const wi = [ 48 | f64(16.0 / 36.0), 4.0 / 36.0, 1.0 / 36.0, 49 | 4.0 / 36.0, 1.0 / 36.0, 4.0 / 36.0, 50 | 1.0 / 36.0, 4.0 / 36.0, 1.0 / 36.0, 51 | ]! 52 | // vfmt on 53 | 54 | // opposite returns vector of opposite direction. Yes Enum can have methods in V. 55 | // Warning: This array must be coherent with Vi enum order ! 56 | fn (v Vi) opposite() Vi { 57 | return opp[int(v)] 58 | } 59 | 60 | // Discrete velocity vectors, by component, with respect to SDL display orientation (North is negative on y axis) 61 | // f64 and int are provided to avoid unnecessary casts. 62 | // Warning: These vectors must be coherent with Vi enum order ! 63 | const dvx_f = [0.0, 0.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, -1.0]! 64 | const dvy_f = [0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, -1.0]! 65 | const dvx_i = [0, 0, 1, 1, 1, 0, -1, -1, -1]! 66 | const dvy_i = [0, -1, -1, 0, 1, 1, 1, 0, -1]! 67 | 68 | struct Cell { 69 | mut: 70 | obstacle bool 71 | sp [9]f64 72 | } 73 | 74 | // Cell.new built, and initializes a default Cell. 75 | // Warning: sp values must be coherent with Vi enum order ! 76 | fn Cell.new(o bool) Cell { 77 | return Cell{ 78 | obstacle: o 79 | sp: [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]! 80 | } // ! means fixed size array ! Will change a day ! 81 | } 82 | 83 | // Return a Cell with all mini-cell set to Zero 84 | fn Cell.zero(o bool) Cell { 85 | return Cell{ 86 | obstacle: o 87 | sp: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]! 88 | } 89 | } 90 | 91 | // normalize perform a normalisation on the cell so that average desnsity is rho0 92 | fn (mut c Cell) normalize() { 93 | rho := c.rho() 94 | for mut v in c.sp { 95 | v *= (rho0 / rho) 96 | } 97 | } 98 | 99 | // randomize add some randomness on the cell. 100 | fn (mut c Cell) randomize(i f64) { 101 | for v in vi { 102 | r := rand.f64() * i 103 | c.sum(v, r) 104 | } 105 | } 106 | 107 | // get returns mini-cell depending on the given speed vector. 108 | fn (c &Cell) get(v Vi) f64 { 109 | return c.sp[int(v)] 110 | } 111 | 112 | // set forces a mini-cell value given its speed vector. 113 | fn (mut c Cell) set(v Vi, value f64) { 114 | c.sp[int(v)] = value 115 | } 116 | 117 | // increase (add value) to a mini-cell value given its speed vector. 118 | fn (mut c Cell) sum(v Vi, value f64) { 119 | c.sp[int(v)] += value 120 | } 121 | 122 | // rho computes whole cell's density 123 | fn (c &Cell) rho() f64 { 124 | mut sum := 0.0 125 | for v in c.sp { 126 | sum += v 127 | } 128 | assert math.is_nan(sum) == false 129 | return sum 130 | } 131 | 132 | // ux computes x (horizontal) component of cell speed vector. 133 | fn (c &Cell) ux() f64 { 134 | rho := c.rho() 135 | r := 1.0 / rho * (c.sp[Vi.north_east] + c.sp[Vi.east] + c.sp[Vi.south_east] - c.sp[Vi.south_west] - c.sp[Vi.west] - c.sp[Vi.north_west]) 136 | assert math.is_nan(r) == false 137 | return r 138 | } 139 | 140 | // uy computes y (vertical) component of cell speed vector. 141 | fn (c &Cell) uy() f64 { 142 | rho := c.rho() 143 | r := 1.0 / rho * (-c.sp[Vi.north] - c.sp[Vi.north_east] - c.sp[Vi.north_west] + 144 | c.sp[Vi.south_east] + c.sp[Vi.south] + c.sp[Vi.south_west]) 145 | assert math.is_nan(r) == false 146 | return r 147 | } 148 | 149 | // ux_no_rho computes x (horizontal) component of cell speed vector, when rho is already known and passed as param. 150 | fn (c &Cell) ux_no_rho(rho f64) f64 { 151 | r := 1.0 / rho * (c.sp[Vi.north_east] + c.sp[Vi.east] + c.sp[Vi.south_east] - c.sp[Vi.south_west] - c.sp[Vi.west] - c.sp[Vi.north_west]) 152 | return r 153 | } 154 | 155 | // uy_no_rho computes y (vertical) component of cell speed vector, when rho is already known and passed as param. 156 | fn (c &Cell) uy_no_rho(rho f64) f64 { 157 | r := 1.0 / rho * (-c.sp[Vi.north] - c.sp[Vi.north_east] - c.sp[Vi.north_west] + 158 | c.sp[Vi.south_east] + c.sp[Vi.south] + c.sp[Vi.south_west]) 159 | return r 160 | } 161 | 162 | // equ computes result of equilibrium function. 163 | fn (c &Cell) equ(i Vi) f64 { 164 | rho := c.rho() 165 | ux := c.ux_no_rho(rho) 166 | uy := c.uy_no_rho(rho) 167 | 168 | t1 := 3.0 * (ux * dvx_f[i] + uy * dvy_f[i]) 169 | mut t2 := (ux * dvx_f[i] + uy * dvy_f[i]) 170 | 171 | t2 *= t2 // t2^2 172 | t2 *= (9.0 / 2.0) 173 | t3 := (3.0 / 2.0) * (ux * ux + uy * uy) 174 | r := wi[i] * rho * (1.0 + t1 + t2 - t3) 175 | return r 176 | } 177 | -------------------------------------------------------------------------------- /examples/sdl_opengl_and_sokol/main.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2022 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module main 5 | 6 | import sdl 7 | import sokol.gfx 8 | 9 | #flag -I @VMODROOT/. 10 | #include "example_shader.h" 11 | 12 | fn C.example_shader_desc(gfx.Backend) &gfx.ShaderDesc 13 | 14 | // Vertex_t makes it possible to model vertex buffer data 15 | // for use with the shader system 16 | struct Vertex_t { 17 | // Position 18 | x f32 19 | y f32 20 | z f32 21 | // Color 22 | r f32 23 | g f32 24 | b f32 25 | a f32 26 | } 27 | 28 | const win_width = 500 29 | const win_height = 300 30 | const sample_count = 4 31 | 32 | pub fn create_desc() gfx.Desc { 33 | return gfx.Desc{ 34 | environment: glue_environment() 35 | } 36 | } 37 | 38 | // create_default_pass creates a default `gfx.Pass` compatible with `SDL` and `sokol.gfx.begin_pass/1`. 39 | pub fn create_default_pass(action gfx.PassAction) gfx.Pass { 40 | return gfx.Pass{ 41 | action: action 42 | swapchain: glue_swapchain() 43 | } 44 | } 45 | 46 | // glue_environment returns a `gfx.Environment` compatible for use with `SDL` specific `gfx.Pass`es. 47 | // The retuned `gfx.Environment` can be used when rendering via `SDL`. 48 | // See also: documentation at the top of thirdparty/sokol/sokol_gfx.h 49 | pub fn glue_environment() gfx.Environment { 50 | mut env := gfx.Environment{} 51 | unsafe { vmemset(&env, 0, int(sizeof(env))) } 52 | env.defaults.color_format = .rgba8 53 | env.defaults.depth_format = .@none 54 | env.defaults.sample_count = sample_count 55 | return env 56 | } 57 | 58 | // glue_swapchain returns a `gfx.Swapchain` compatible for use with `SDL` specific display/rendering `gfx.Pass`es. 59 | // The retuned `gfx.Swapchain` can be used when rendering via `SDL`. 60 | // See also: documentation at the top of thirdparty/sokol/sokol_gfx.h 61 | pub fn glue_swapchain() gfx.Swapchain { 62 | mut swapchain := gfx.Swapchain{} 63 | unsafe { vmemset(&swapchain, 0, int(sizeof(swapchain))) } 64 | swapchain.width = win_width 65 | swapchain.height = win_height 66 | swapchain.sample_count = sample_count 67 | swapchain.color_format = .rgba8 68 | swapchain.depth_format = .@none 69 | swapchain.gl.framebuffer = 0 // use default framebuffer (usually 0) 70 | return swapchain 71 | } 72 | 73 | @[console] 74 | fn main() { 75 | sdl.init(sdl.init_video) 76 | 77 | $if wasm32_emscripten || android { 78 | sdl.gl_set_attribute(.context_profile_mask, int(sdl.GLprofile.es)) 79 | sdl.gl_set_attribute(.context_major_version, 3) 80 | } $else { 81 | sdl.gl_set_attribute(.context_flags, int(sdl.GLcontextFlag.forward_compatible_flag)) 82 | sdl.gl_set_attribute(.context_profile_mask, int(sdl.GLprofile.core)) 83 | sdl.gl_set_attribute(.context_major_version, 4) 84 | sdl.gl_set_attribute(.context_minor_version, 1) 85 | } 86 | sdl.gl_set_attribute(.doublebuffer, 1) 87 | sdl.gl_set_attribute(.depth_size, 24) 88 | sdl.gl_set_attribute(.stencil_size, 8) 89 | 90 | mut window_flags := u32(sdl.WindowFlags.opengl) 91 | window := sdl.create_window('Hello SDL2 + Sokol (OpenGL)'.str, 300, 300, win_width, 92 | win_height, window_flags) 93 | if window == sdl.null { 94 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 95 | panic('Could not create SDL window, SDL says:\n${error_msg}') 96 | } 97 | 98 | gl_context := sdl.gl_create_context(window) 99 | if gl_context == sdl.null { 100 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 101 | panic('Could not create OpenGL context, SDL says:\n${error_msg}') 102 | } 103 | 104 | sdl.gl_make_current(window, gl_context) 105 | // Enable VSYNC (Sync buffer swaps with monitors vertical refresh rate) 106 | if sdl.gl_set_swap_interval(1) < 0 { 107 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 108 | panic('Could not set OpenGL swap interval to vsync:\n${error_msg}') 109 | } 110 | 111 | desc := create_desc() 112 | gfx.setup(&desc) 113 | assert gfx.is_valid() == true 114 | 115 | pass_action := gfx.create_clear_pass_action(0.0, 0.0, 0.0, 1.0) 116 | pass := create_default_pass(pass_action) 117 | mut bind := gfx.Bindings{} 118 | 119 | vertices := [ 120 | Vertex_t{0.0, 0.5, 0.5, 1.0, 0.0, 0.0, 1.0}, 121 | Vertex_t{0.5, -0.5, 0.5, 0.0, 1.0, 0.0, 1.0}, 122 | Vertex_t{-0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0}, 123 | ] 124 | 125 | mut vertex_buffer_desc := gfx.BufferDesc{ 126 | label: c'triangle-vertices' 127 | } 128 | unsafe { vmemset(&vertex_buffer_desc, 0, int(sizeof(vertex_buffer_desc))) } 129 | 130 | vertex_buffer_desc.size = usize(vertices.len * int(sizeof(Vertex_t))) 131 | vertex_buffer_desc.data = gfx.Range{ 132 | ptr: vertices.data 133 | size: vertex_buffer_desc.size 134 | } 135 | 136 | bind.vertex_buffers[0] = gfx.make_buffer(&vertex_buffer_desc) 137 | 138 | shader := gfx.make_shader(C.example_shader_desc(gfx.query_backend())) 139 | 140 | mut pipeline_desc := gfx.PipelineDesc{} 141 | unsafe { vmemset(&pipeline_desc, 0, int(sizeof(pipeline_desc))) } 142 | 143 | pipeline_desc.shader = shader 144 | 145 | pipeline_desc.layout.attrs[C.ATTR_vs_position].format = .float3 // x,y,z as f32 146 | pipeline_desc.layout.attrs[C.ATTR_vs_color0].format = .float4 // r, g, b, a as f32 147 | 148 | pipeline_desc.label = c'triangle-pipeline' 149 | 150 | shader_pipeline := gfx.make_pipeline(&pipeline_desc) 151 | 152 | mut should_close := false 153 | 154 | for { 155 | evt := sdl.Event{} 156 | for 0 < sdl.poll_event(&evt) { 157 | match evt.@type { 158 | .quit { should_close = true } 159 | else {} 160 | } 161 | } 162 | if should_close { 163 | break 164 | } 165 | 166 | gfx.begin_pass(&pass) 167 | 168 | gfx.apply_pipeline(shader_pipeline) 169 | gfx.apply_bindings(&bind) 170 | 171 | gfx.draw(0, 3, 1) 172 | gfx.end_pass() 173 | gfx.commit() 174 | 175 | sdl.gl_swap_window(window) 176 | } 177 | 178 | gfx.shutdown() 179 | sdl.gl_delete_context(gl_context) 180 | sdl.destroy_window(window) 181 | sdl.quit() 182 | } 183 | -------------------------------------------------------------------------------- /shape.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_shape.h 8 | // 9 | 10 | pub const nonshapeable_window = C.SDL_NONSHAPEABLE_WINDOW // -1 11 | 12 | pub const invalid_shape_argument = C.SDL_INVALID_SHAPE_ARGUMENT // -2 13 | 14 | pub const window_lacks_shape = C.SDL_WINDOW_LACKS_SHAPE // -3 15 | 16 | fn C.SDL_CreateShapedWindow(title &char, x u32, y u32, w u32, h u32, flags u32) &C.SDL_Window 17 | 18 | // create_shaped_window creates a window that can be shaped with the specified position, dimensions, 19 | // and flags. 20 | // 21 | // `title` The title of the window, in UTF-8 encoding. 22 | // `x` The x position of the window, ::SDL_WINDOWPOS_CENTERED, or 23 | // ::SDL_WINDOWPOS_UNDEFINED. 24 | // `y` The y position of the window, ::SDL_WINDOWPOS_CENTERED, or 25 | // ::SDL_WINDOWPOS_UNDEFINED. 26 | // `w` The width of the window. 27 | // `h` The height of the window. 28 | // `flags` The flags for the window, a mask of SDL_WINDOW_BORDERLESS with 29 | // any of the following: ::SDL_WINDOW_OPENGL, 30 | // ::SDL_WINDOW_INPUT_GRABBED, ::SDL_WINDOW_HIDDEN, 31 | // ::SDL_WINDOW_RESIZABLE, ::SDL_WINDOW_MAXIMIZED, 32 | // ::SDL_WINDOW_MINIMIZED, ::SDL_WINDOW_BORDERLESS is always set, 33 | // and ::SDL_WINDOW_FULLSCREEN is always unset. 34 | // returns the window created, or NULL if window creation failed. 35 | // 36 | // NOTE This function is available since SDL 2.0.0. 37 | // 38 | // See also: SDL_DestroyWindow 39 | pub fn create_shaped_window(title &char, x u32, y u32, w u32, h u32, flags u32) &Window { 40 | return C.SDL_CreateShapedWindow(title, x, y, w, h, flags) 41 | } 42 | 43 | fn C.SDL_IsShapedWindow(window &C.SDL_Window) bool 44 | 45 | // is_shaped_window returns whether the given window is a shaped window. 46 | // 47 | // `window` The window to query for being shaped. 48 | // returns SDL_TRUE if the window is a window that can be shaped, SDL_FALSE if 49 | // the window is unshaped or NULL. 50 | // 51 | // NOTE This function is available since SDL 2.0.0. 52 | // 53 | // See also: SDL_CreateShapedWindow 54 | pub fn is_shaped_window(window &Window) bool { 55 | return C.SDL_IsShapedWindow(window) 56 | } 57 | 58 | // WindowShapeMode is an enum denoting the specific type of contents present in an SDL_WindowShapeParams union. 59 | // WindowShapeMode is C.WindowShapeMode 60 | pub enum WindowShapeModeFlag { 61 | default = C.ShapeModeDefault // The default mode, a binarized alpha cutoff of 1. 62 | binarize_alpha = C.ShapeModeBinarizeAlpha // A binarized alpha cutoff with a given integer value. 63 | reverse_binarize_alpha = C.ShapeModeReverseBinarizeAlpha // A binarized alpha cutoff with a given integer value, but with the opposite comparison. 64 | color_key = C.ShapeModeColorKey // A color key is applied. 65 | } 66 | 67 | fn C.SDL_SHAPEMODEALPHA(mode WindowShapeModeFlag) bool 68 | pub fn shapemodealpha(mode WindowShapeModeFlag) bool { 69 | return C.SDL_SHAPEMODEALPHA(mode) 70 | } 71 | 72 | // WindowShapeParams is a union containing parameters for shaped windows. 73 | // WindowShapeParams is C.SDL_WindowShapeParams 74 | @[typedef] 75 | union C.SDL_WindowShapeParams { 76 | pub mut: 77 | binarizationCutoff u8 // A cutoff alpha value for binarization of the window shape's alpha channel. 78 | colorKey Color 79 | } 80 | 81 | pub type WindowShapeParams = C.SDL_WindowShapeParams 82 | 83 | // WindowShapeMode is a struct that tags the SDL_WindowShapeParams union with 84 | // an enum describing the type of its contents. 85 | // WindowShapeMode is C.SDL_WindowShapeMode 86 | @[typedef] 87 | pub struct C.SDL_WindowShapeMode { 88 | pub: 89 | mode WindowShapeModeFlag // The mode of these window-shape parameters. 90 | parameters WindowShapeParams // Window-shape parameters. 91 | } 92 | 93 | pub type WindowShapeMode = C.SDL_WindowShapeMode 94 | 95 | fn C.SDL_SetWindowShape(window &C.SDL_Window, shape &C.SDL_Surface, shape_mode &C.SDL_WindowShapeMode) int 96 | 97 | // set_window_shape sets the shape and parameters of a shaped window. 98 | // 99 | // `window` The shaped window whose parameters should be set. 100 | // `shape` A surface encoding the desired shape for the window. 101 | // `shape_mode` The parameters to set for the shaped window. 102 | // returns 0 on success, SDL_INVALID_SHAPE_ARGUMENT on an invalid shape 103 | // argument, or SDL_NONSHAPEABLE_WINDOW if the SDL_Window given does 104 | // not reference a valid shaped window. 105 | // 106 | // NOTE This function is available since SDL 2.0.0. 107 | // 108 | // See also: SDL_WindowShapeMode 109 | // See also: SDL_GetShapedWindowMode 110 | pub fn set_window_shape(window &Window, shape &Surface, shape_mode &WindowShapeMode) int { 111 | return C.SDL_SetWindowShape(window, shape, shape_mode) 112 | } 113 | 114 | fn C.SDL_GetShapedWindowMode(window &C.SDL_Window, shape_mode &C.SDL_WindowShapeMode) int 115 | 116 | // get_shaped_window_mode gets the shape parameters of a shaped window. 117 | // 118 | // `window` The shaped window whose parameters should be retrieved. 119 | // `shape_mode` An empty shape-mode structure to fill, or NULL to check 120 | // whether the window has a shape. 121 | // returns 0 if the window has a shape and, provided shape_mode was not NULL, 122 | // shape_mode has been filled with the mode data, 123 | // SDL_NONSHAPEABLE_WINDOW if the SDL_Window given is not a shaped 124 | // window, or SDL_WINDOW_LACKS_SHAPE if the SDL_Window given is a 125 | // shapeable window currently lacking a shape. 126 | // 127 | // NOTE This function is available since SDL 2.0.0. 128 | // 129 | // See also: SDL_WindowShapeMode 130 | // See also: SDL_SetWindowShape 131 | pub fn get_shaped_window_mode(window &Window, shape_mode &WindowShapeMode) int { 132 | return C.SDL_GetShapedWindowMode(window, shape_mode) 133 | } 134 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sdl 2 | 3 | `sdl` is a SDL V module and a wrapper around [libSDL](https://www.libsdl.org/). 4 | Both SDL2 and SDL3 versions are supported through dedicated [branches](https://github.com/vlang/sdl/branches). 5 | 6 | The module strives to support 100% of the SDL API. 7 | 8 | So, among many other things, you can: 9 | - Open windows and accelerated rendering contexts 10 | - Render basic 2D graphics 11 | - Handle input events from keyboards, touches, mice, gamepads and joysticks 12 | - Play audio, sound effects and music 13 | 14 | ## Project Navigation 15 | 16 | You are currently reading the instructions for **SDL2**. 17 | For SDL3 instructions, see the `README.md` in any of the `3.x.x` [branches](https://github.com/vlang/sdl/branches). 18 | 19 | ## Install 20 | 21 | To use `vlang/sdl` you need SDL2 libraries installed and the corresponding 22 | `vlang/sdl` *branch* checked out that *matches the SDL2 version installed* on the target system. 23 | 24 | See [Dependencies](#Dependencies) section below for how to install SDL2 25 | for different OSes and systems. 26 | 27 | If you have SDL2 version `2.30.x` installed on your system you can simply do: 28 | ```bash 29 | v install sdl 30 | v ~/.vmodules/sdl/setup.vsh 31 | ``` 32 | 33 | If you want to use another version of SDL2 you will, currently, have to install 34 | it via `git` or by manual download. 35 | 36 | An example of installing the system provided version of SDL2 via `git`: 37 | ```bash 38 | git clone https://github.com/vlang/sdl.git ~/.vmodules/sdl 39 | v ~/.vmodules/sdl/setup.vsh 40 | ``` 41 | 42 | Should `sdl2-config` be absent on your system you can try the following instead, 43 | by providing the version manually: 44 | 45 | An example of installing the `2.0.12` branch (that *matches* SDL2 version 2.0.12) via `git`: 46 | ```bash 47 | git clone https://github.com/vlang/sdl.git ~/.vmodules/sdl 48 | cd ~/.vmodules/sdl 49 | git checkout 2.0.12 50 | ``` 51 | ... and for Windows in cmd.exe: 52 | ```bash 53 | git clone https://github.com/vlang/sdl.git %HOMEPATH%/.vmodules/sdl 54 | cd %HOMEPATH%/.vmodules/sdl 55 | git checkout 2.0.12 56 | ``` 57 | ... and for Windows in PowerShell (PS): 58 | ```bash 59 | git clone https://github.com/vlang/sdl.git "$HOME/.vmodules/sdl" 60 | cd "$HOME/.vmodules/sdl" 61 | git checkout 2.0.12 62 | ``` 63 | 64 | Then follow the steps in the [Windows](#windows) section below. 65 | 66 | You can see what `sdl` releases are available in the [GitHub repository](https://github.com/vlang/sdl/branches) via branches. 67 | 68 | ## Notes 69 | 70 | ### Versions 71 | 72 | SDL2 `v2.0.8` is currently the lowest version of SDL2 supported. 73 | SDL2 is backwards compatible - so anything written against `v2.0.8` can be compiled and run 74 | against newer versions of the SDL2 library. 75 | 76 | Also note that SDL2 **is not** compatible with SDL `v1.x`. 77 | SDL2 is however compatible with SDL3 through the [`sdl2-compat`](https://github.com/libsdl-org/sdl2-compat) layer. 78 | Which makes it possible to use the SDL2 API through the SDL3 libraries. 79 | You can tell `sdl` to use this compatibility layer on systems that support `pkgconfig` by 80 | passing the compile time flag `-d sdl_compat` when building your `sdl`/SDL2 based V application. 81 | 82 | ### Notes on garbage collection and memory issues 83 | 84 | Currently, with some setups, SDL2 is known to trigger crashes when used in conjunction 85 | with V's default garbage collector. Because of this you have to explicitly **opt-in** 86 | to use V's garbage collection with SDL2. 87 | 88 | If you choose to use the garbage collector with SDL objects 89 | (by running apps importing `sdl` with `v -d sdl_use_gc run`) 90 | you may experience runtime crashes and output similar to this: 91 | 92 | ``` 93 | main__main: RUNTIME ERROR: invalid memory access 94 | ``` 95 | 96 | We are tracking the issue here: https://github.com/vlang/sdl/issues/744 97 | 98 | The crashes can be avoided by simply **not** passing `-d sdl_use_gc` and 99 | managing memory manually with SDL's memory functions like `sdl.free/1`, `sdl.malloc/1`, 100 | `sdl.calloc/2`, `sdl.realloc/2` and the various `create_*` and `destroy` functions. 101 | 102 | ## Support 103 | 104 | `sdl` is currently supported on: 105 | - Linux 106 | - MacOS (via [homebrew](https://brew.sh/)) 107 | - Windows 108 | 109 | ## Examples 110 | 111 | [tVintris](examples/tvintris) 112 | 113 | ![tVintris screenshot](/examples/assets/images/tvintris.png) 114 | 115 | You can run the tVintris example like this : 116 | ``` 117 | v run sdl/examples/tvintris/tvintris.v 118 | ``` 119 | 120 | ## Dependencies 121 | 122 | ### Linux 123 | 124 | #### Fedora 125 | ```bash 126 | sudo dnf install SDL2-devel SDL2_ttf-devel SDL2_mixer-devel SDL2_image-devel 127 | ``` 128 | #### Ubuntu 129 | ```bash 130 | sudo apt install libsdl2-ttf-dev libsdl2-mixer-dev libsdl2-image-dev 131 | ``` 132 | 133 | #### Arch 134 | ```bash 135 | sudo pacman -S sdl2 sdl2_image sdl2_mixer sdl2_ttf 136 | ``` 137 | 138 | #### ClearLinux 139 | ```bash 140 | sudo swupd bundle-add devpkg-SDL2_ttf devpkg-SDL2_mixer devpkg-SDL2_image 141 | ``` 142 | 143 | ### MacOS 144 | 145 | #### Brew 146 | ```bash 147 | brew install sdl2 sdl2_gfx sdl2_ttf sdl2_mixer sdl2_image sdl2_net 148 | ``` 149 | 150 | If you get no music with the above, try: 151 | ```bash 152 | brew reinstall --build-from-source --force sdl2 sdl2_gfx sdl2_image sdl2_mixer sdl2_net sdl2_ttf webp libtiff libmodplug libogg 153 | ``` 154 | 155 | ### Windows 156 | It is necessary to install the SDL2 development libraries for Windows. 157 | 158 | To do this, run this in cmd.exe: 159 | ```bash 160 | cd %HOMEPATH%\.vmodules\sdl 161 | v run windows_install_dependencies.vsh 162 | ``` 163 | 164 | In Powershell, instead of the above, run this: 165 | ```bash 166 | cd "$HOME/.vmodules/sdl" 167 | v run windows_install_dependencies.vsh 168 | ``` 169 | 170 | This will create a directory called "thirdparty" which will be used to download and 171 | extract the required libraries. To successfully run a provided example or your own projects, 172 | the sdl dlls must be copied to the main application directory. e.g.: 173 | ```bash 174 | copy thirdparty\SDL2-2.30.0\lib\x64\SDL2.dll examples\basic_window\ 175 | cd .. 176 | v run sdl\examples\basic_window\main.v 177 | ``` 178 | 179 | ## Contributions 180 | 181 | - nsauzede 182 | - spytheman 183 | - adlesh 184 | - Larpon 185 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: General CI 2 | 3 | on: 4 | push: 5 | paths-ignore: 6 | - "**.md" 7 | pull_request: 8 | paths-ignore: 9 | - "**.md" 10 | 11 | jobs: 12 | ubuntu-tcc: 13 | runs-on: ubuntu-latest 14 | timeout-minutes: 30 15 | env: 16 | VFLAGS: -cc tcc -no-retry-compilation 17 | SDL2_VERSION: 2.30.0 18 | steps: 19 | - name: Install dependencies 20 | run: | 21 | sudo apt-get update 22 | sudo apt-get install --quiet -y libsdl2-dev libsdl2-ttf-dev 23 | sudo apt-get install --quiet -y libsdl2-mixer-dev libsdl2-image-dev 24 | curl -L https://www.libsdl.org/release/SDL2-${SDL2_VERSION}.tar.gz -o SDL2.tar.gz 25 | tar -zxvf SDL2.tar.gz 26 | 27 | - name: Build SDL 28 | run: | 29 | cd SDL2-${SDL2_VERSION} 30 | mkdir build 31 | cd build 32 | ../configure --prefix /tmp/sdl2-${SDL2_VERSION} 33 | make 34 | make install 35 | 36 | - name: Install V 37 | uses: vlang/setup-v@v1 38 | with: 39 | check-latest: true 40 | 41 | - name: Checkout SDL 42 | uses: actions/checkout@v4 43 | with: 44 | path: sdl 45 | 46 | - name: Link local SDL folder in ~/.vmodules/sdl 47 | run: | 48 | cd sdl 49 | mkdir -p ~/.vmodules 50 | ln -s $(pwd) ~/.vmodules/sdl 51 | 52 | - name: Test code formatting 53 | run: | 54 | cd sdl 55 | v test-fmt 56 | v fmt -verify . 57 | 58 | - name: Build sdl shared 59 | run: | 60 | export CFLAGS="$(/tmp/sdl2-${SDL2_VERSION}/bin/sdl2-config --cflags --libs)" 61 | v -shared -g sdl 62 | 63 | - name: Run tests 64 | run: v test sdl 65 | 66 | - name: Build sdl examples 67 | run: | 68 | v shader sdl/examples/sdl_opengl_and_sokol 69 | export CFLAGS="$(/tmp/sdl2-${SDL2_VERSION}/bin/sdl2-config --cflags --libs)" 70 | v run sdl/examples/versions 71 | v should-compile-all sdl/examples/ 72 | 73 | - name: Test SDL version 74 | run: | 75 | export CFLAGS="$(/tmp/sdl2-${SDL2_VERSION}/bin/sdl2-config --cflags --libs)" 76 | VER="$(v run sdl/examples/version)" 77 | echo "${SDL2_VERSION} == $VER ?" 78 | test "${SDL2_VERSION}" = "$VER" || exit 1 79 | 80 | macos: 81 | runs-on: macos-13 82 | timeout-minutes: 60 83 | env: 84 | SDL2_VERSION: 2.32.6 85 | CFLAGS: -fpermissive -std=c99 86 | steps: 87 | - name: Checkout V 88 | uses: actions/checkout@v4 89 | with: 90 | repository: vlang/v 91 | 92 | - name: Build local v 93 | run: make && ./v symlink 94 | 95 | - name: Install dependencies 96 | run: | 97 | brew install sdl2_ttf sdl2_mixer sdl2_image 98 | 99 | - name: Checkout SDL 100 | uses: actions/checkout@v4 101 | with: 102 | path: sdl 103 | ref: 2.30.0 104 | 105 | - name: Link local SDL folder in ~/.vmodules/sdl 106 | run: | 107 | cd sdl 108 | mkdir -p ~/.vmodules 109 | ln -s $(pwd) ~/.vmodules/sdl 110 | 111 | - name: Test code formatting 112 | run: | 113 | cd sdl 114 | VJOBS=1 v test-fmt 115 | VJOBS=1 v fmt -verify . 116 | 117 | - name: Build sdl shared 118 | run: | 119 | export CFLAGS="$(sdl2-config --cflags --libs)" 120 | v -shared -g sdl 121 | 122 | - name: Run tests 123 | run: v test sdl 124 | 125 | - name: Build sdl examples 126 | run: | 127 | v shader sdl/examples/sdl_opengl_and_sokol 128 | export CFLAGS="$(sdl2-config --cflags --libs)" 129 | v run sdl/examples/versions 130 | v should-compile-all sdl/examples/ 131 | 132 | - name: Test SDL version 133 | run: | 134 | export CFLAGS="$(sdl2-config --cflags --libs)" 135 | VER="$(v run sdl/examples/version)" 136 | echo "${SDL2_VERSION} == $VER ?" 137 | test "${SDL2_VERSION}" = "$VER" || exit 1 138 | 139 | windows-gcc: 140 | runs-on: windows-latest 141 | timeout-minutes: 30 142 | env: 143 | VFLAGS: -cc gcc -no-retry-compilation 144 | SDL2_VERSION: 2.30.0 145 | steps: 146 | - name: Install V 147 | uses: vlang/setup-v@v1 148 | with: 149 | check-latest: true 150 | 151 | - name: Checkout SDL 152 | uses: actions/checkout@v4 153 | with: 154 | path: sdl 155 | 156 | - name: Run tests 157 | run: v test sdl 158 | 159 | - name: Install dependencies 160 | run: v run sdl/windows_install_dependencies.vsh 161 | 162 | - name: Move SDL folder to ~/.vmodules/sdl 163 | run: | 164 | move-item -force sdl $home\.vmodules\ 165 | 166 | - name: Build sdl examples 167 | run: | 168 | $sdl_home = "$home\.vmodules\sdl" 169 | copy-item $sdl_home\thirdparty\SDL2-${env:SDL2_VERSION}\lib\x64\SDL2.dll $sdl_home\examples\versions\ 170 | v run $sdl_home\examples\versions 171 | v shader $sdl_home\examples\sdl_opengl_and_sokol 172 | v should-compile-all $sdl_home\examples\ 173 | 174 | windows-tcc: 175 | runs-on: windows-latest 176 | timeout-minutes: 30 177 | env: 178 | VFLAGS: -cc tcc -no-retry-compilation 179 | SDL2_VERSION: 2.30.0 180 | steps: 181 | - name: Install V 182 | uses: vlang/setup-v@v1 183 | with: 184 | check-latest: true 185 | 186 | - name: Checkout SDL 187 | uses: actions/checkout@v4 188 | with: 189 | path: sdl 190 | 191 | - name: Run tests 192 | run: v test sdl 193 | 194 | - name: Install dependencies 195 | run: v run sdl/windows_install_dependencies.vsh 196 | 197 | - name: Move SDL folder to ~/.vmodules/sdl 198 | run: | 199 | move-item -force sdl $home\.vmodules\ 200 | 201 | - name: Build sdl examples 202 | run: | 203 | $sdl_home = "$home\.vmodules\sdl" 204 | copy-item $sdl_home\thirdparty\SDL2-${env:SDL2_VERSION}\lib\x64\SDL2.dll $sdl_home\examples\versions\ 205 | v run $sdl_home\examples\versions 206 | v shader $sdl_home\examples\sdl_opengl_and_sokol 207 | v should-compile-all $sdl_home\examples\ 208 | -------------------------------------------------------------------------------- /version.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_version.h 8 | // 9 | 10 | pub const major_version = C.SDL_MAJOR_VERSION // 2 11 | 12 | pub const minor_version = C.SDL_MINOR_VERSION // 30 13 | 14 | pub const patchlevel = C.SDL_PATCHLEVEL // 0 15 | 16 | // Version is information about the version of SDL in use. 17 | // 18 | // Represents the library's version as three levels: major revision 19 | // (increments with massive changes, additions, and enhancements), 20 | // minor revision (increments with backwards-compatible changes to the 21 | // major revision), and patchlevel (increments with fixes to the minor 22 | // revision). 23 | // 24 | // See also: SDL_VERSION 25 | // See also: SDL_GetVersion 26 | @[typedef] 27 | pub struct C.SDL_version { 28 | pub: 29 | major u8 // major version 30 | minor u8 // minor version 31 | patch u8 // update version 32 | } 33 | 34 | pub fn (ver C.SDL_version) str() string { 35 | return '${ver.major}.${ver.minor}.${ver.patch}' 36 | } 37 | 38 | pub type Version = C.SDL_version 39 | 40 | fn C.SDL_VERSION(ver &C.SDL_version) 41 | 42 | // SDL_VERSION is a macro to determine SDL version program was compiled against. 43 | // 44 | // This macro fills in a SDL_version structure with the version of the 45 | // library you compiled against. This is determined by what header the 46 | // compiler uses. Note that if you dynamically linked the library, you might 47 | // have a slightly newer or older version at runtime. That version can be 48 | // determined with SDL_GetVersion(), which, unlike SDL_VERSION(), 49 | // is not a macro. 50 | // 51 | // `x` A pointer to a SDL_version struct to initialize. 52 | // 53 | // See also: SDL_version 54 | // See also: SDL_GetVersion 55 | pub fn version(mut ver Version) { 56 | C.SDL_VERSION(&ver) 57 | } 58 | 59 | // This macro turns the version numbers into a numeric value: 60 | /* 61 | ``` 62 | (1,2,3) -> (1203) 63 | ``` 64 | */ 65 | // 66 | // This assumes that there will never be more than 100 patchlevels. 67 | // 68 | // In versions higher than 2.9.0, the minor version overflows into 69 | // the thousands digit: for example, 2.23.0 is encoded as 4300, 70 | // and 2.255.99 would be encoded as 25799. 71 | // This macro will not be available in SDL 3.x. 72 | pub fn C.SDL_VERSIONNUM(x int, y int, z int) int 73 | 74 | // SDL_COMPILEDVERSION is the version number macro for the current SDL version. 75 | // 76 | // In versions higher than 2.9.0, the minor version overflows into 77 | // the thousands digit: for example, 2.23.0 is encoded as 4300. 78 | // This macro will not be available in SDL 3.x. 79 | // 80 | // Deprecated, use SDL_VERSION_ATLEAST or SDL_VERSION instead. 81 | pub fn C.SDL_COMPILEDVERSION() int 82 | 83 | // SDL_VERSION_ATLEAST macro will evaluate to true if compiled with SDL at least X.Y.Z. 84 | pub fn C.SDL_VERSION_ATLEAST(x int, y int, z int) bool 85 | 86 | fn C.SDL_GetVersion(ver &C.SDL_version) 87 | 88 | // get_version gets the version of SDL that is linked against your program. 89 | // 90 | // If you are linking to SDL dynamically, then it is possible that the 91 | // current version will be different than the version you compiled against. 92 | // This function returns the current version, while SDL_VERSION() is a 93 | // macro that tells you what version you compiled with. 94 | // 95 | /* 96 | ``` 97 | SDL_version compiled; 98 | SDL_version linked; 99 | 100 | SDL_VERSION(&compiled); 101 | SDL_GetVersion(&linked); 102 | printf("We compiled against SDL version %d.%d.%d ...\n", compiled.major, compiled.minor, compiled.patch); 103 | printf("But we linked against SDL version %d.%d.%d.\n", linked.major, linked.minor, linked.patch); 104 | ``` 105 | */ 106 | // 107 | // This function may be called safely at any time, even before SDL_Init(). 108 | // 109 | // `ver` the SDL_version structure that contains the version information 110 | // 111 | // NOTE This function is available since SDL 2.0.0. 112 | // 113 | // See also: SDL_VERSION 114 | // Seealso: SDL_GetRevision 115 | pub fn get_version(mut ver Version) { 116 | C.SDL_GetVersion(&ver) 117 | } 118 | 119 | fn C.SDL_GetRevision() &char 120 | 121 | // get_revision gets the code revision of SDL that is linked against your program. 122 | // 123 | // This value is the revision of the code you are linked with and may be 124 | // different from the code you are compiling with, which is found in the 125 | // constant SDL_REVISION. 126 | // 127 | // The revision is arbitrary string (a hash value) uniquely identifying the 128 | // exact revision of the SDL library in use, and is only useful in comparing 129 | // against other revisions. It is NOT an incrementing number. 130 | // 131 | // If SDL wasn't built from a git repository with the appropriate tools, this 132 | // will return an empty string. 133 | // 134 | // Prior to SDL 2.0.16, before development moved to GitHub, this returned a 135 | // hash for a Mercurial repository. 136 | // 137 | // You shouldn't use this function for anything but logging it for debugging 138 | // purposes. The string is not intended to be reliable in any way. 139 | // 140 | // returns an arbitrary string, uniquely identifying the exact revision of 141 | // the SDL library in use. 142 | // 143 | // NOTE This function is available since SDL 2.0.0. 144 | // 145 | // See also: SDL_GetVersion 146 | pub fn get_revision() &char { 147 | return C.SDL_GetRevision() 148 | } 149 | 150 | fn C.SDL_GetRevisionNumber() int 151 | 152 | // get_revision_number is an obsolete function, do not use. 153 | // 154 | // When SDL was hosted in a Mercurial repository, and was built carefully, 155 | // this would return the revision number that the build was created from. This 156 | // number was not reliable for several reasons, but more importantly, SDL is 157 | // now hosted in a git repository, which does not offer numbers at all, only 158 | // hashes. This function only ever returns zero now. Don't use it. 159 | // 160 | // Before SDL 2.0.16, this might have returned an unreliable, but non-zero 161 | // number. 162 | // 163 | // deprecated Use SDL_GetRevision() instead; if SDL was carefully built, it 164 | // will return a git hash. 165 | // 166 | // returns zero, always, in modern SDL releases. 167 | // 168 | // NOTE This function is available since SDL 2.0.0. 169 | // 170 | // See also SDL_GetRevision 171 | @[deprecated: 'Use SDL_GetRevision() instead; if SDL was carefully built, it will return a git hash.'] 172 | pub fn get_revision_number() int { 173 | return C.SDL_GetRevisionNumber() 174 | } 175 | -------------------------------------------------------------------------------- /examples/lbm/lattice.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import math 4 | 5 | pub struct Lattice { 6 | w int 7 | h int 8 | mut: 9 | m []Cell 10 | } 11 | 12 | // Allocate x*y Cells Lattice 13 | pub fn Lattice.new(x int, y int, profile &u8) Lattice { 14 | mut ret := Lattice{x, y, []Cell{cap: x * y}} 15 | 16 | for i in 0 .. (x * y) { 17 | e := unsafe { profile[i] != 0 } 18 | mut c := Cell.new(e) 19 | ret.m << c 20 | } 21 | return ret 22 | } 23 | 24 | pub fn (l Lattice) str() string { 25 | return 'Lattice[${l.w}x${l.h}]' 26 | } 27 | 28 | // total_rho compute the total density on the Lattice. This value is conserved. 29 | pub fn (l Lattice) total_rho() f64 { 30 | mut t := 0.0 31 | for c in l.m { 32 | if c.obstacle { 33 | continue 34 | } 35 | t += c.rho() 36 | } 37 | return t 38 | } 39 | 40 | // clear the Lattice : File fields with zeros. 41 | pub fn (mut l Lattice) clear() { 42 | unsafe { vmemset(l.m.data, 0, u32(l.m.len) * sizeof(Cell)) } 43 | } 44 | 45 | // add_flow create an artificial flow of i intensity in v direction 46 | // It impacts all lattice cells. It's usually a good thing to call normalize() 47 | // method after that. 48 | pub fn (mut l Lattice) add_flow(i f64, v Vi) { 49 | for mut c in l.m { 50 | if c.obstacle { 51 | continue 52 | } 53 | c.sum(v, i) 54 | } 55 | } 56 | 57 | // normalize normalizes all lattice cells against rho0 so that average density 58 | // is equal to rho0. 59 | pub fn (mut l Lattice) normalize() { 60 | for mut c in l.m { 61 | if c.obstacle { 62 | continue 63 | } 64 | c.normalize() 65 | } 66 | } 67 | 68 | // max_ux returns maximal horizontal speed in the whole lattice 69 | pub fn (l Lattice) max_ux() f64 { 70 | mut ux := 0.0 71 | 72 | for c in l.m { 73 | if c.obstacle { 74 | continue 75 | } 76 | u := c.ux() 77 | 78 | if u > ux { 79 | ux = u 80 | } 81 | } 82 | return ux 83 | } 84 | 85 | // min_ux returns minimal horizontal speed in the whole lattice 86 | pub fn (l Lattice) min_ux() f64 { 87 | mut ux := 0.0 88 | 89 | for c in l.m { 90 | if c.obstacle { 91 | continue 92 | } 93 | u := c.ux() 94 | 95 | if u < ux { 96 | ux = u 97 | } 98 | } 99 | return ux 100 | } 101 | 102 | // max_uy returns maximal horizontal speed in the whole lattice 103 | pub fn (l Lattice) max_uy() f64 { 104 | mut uy := 0.0 105 | 106 | for c in l.m { 107 | if c.obstacle { 108 | continue 109 | } 110 | u := c.uy() 111 | 112 | if u > uy { 113 | uy = u 114 | } 115 | } 116 | return uy 117 | } 118 | 119 | // min_uy returns minimal horizontal speed in the whole lattice 120 | pub fn (l Lattice) min_uy() f64 { 121 | mut uy := 0.0 122 | 123 | for c in l.m { 124 | if c.obstacle { 125 | continue 126 | } 127 | u := c.uy() 128 | 129 | if u < uy { 130 | uy = u 131 | } 132 | } 133 | return uy 134 | } 135 | 136 | // max_rho returns maximal cell density in the whole lattice 137 | pub fn (l Lattice) max_rho() f64 { 138 | mut r := 0.0 139 | 140 | for c in l.m { 141 | if c.obstacle { 142 | continue 143 | } 144 | rho := c.rho() 145 | 146 | if rho > r { 147 | r = rho 148 | } 149 | } 150 | return r 151 | } 152 | 153 | // min_rho returns maximal cell density in the whole lattice 154 | pub fn (l Lattice) min_rho() f64 { 155 | mut r := 1_000_000.0 156 | 157 | for c in l.m { 158 | if c.obstacle { 159 | continue 160 | } 161 | rho := c.rho() 162 | 163 | if rho < r { 164 | r = rho 165 | } 166 | } 167 | return r 168 | } 169 | 170 | // mean_rho returns the mean rho value over all lattice 171 | fn (l Lattice) mean_rho() f64 { 172 | mut i := 0.0 173 | for c in l.m { 174 | if c.obstacle { 175 | continue 176 | } 177 | i += c.rho() 178 | } 179 | 180 | return i / l.m.len 181 | } 182 | 183 | // vorticity computes vorticity at given position. 184 | fn (l Lattice) vorticity(x int, y int) f64 { 185 | if x > 0 && x < l.w - 1 { 186 | if y > 0 && y < l.h - 1 { 187 | ind := y * l.w + x 188 | omega := (l.m[ind + 1].uy() - l.m[ind - 1].uy()) - (l.m[ind + l.w].ux() - l.m[ind - l.w].ux()) 189 | return omega 190 | } 191 | } 192 | return 0 193 | } 194 | 195 | // randomize add random noise everywhere given i intensity. 196 | // It's usually a good thing to call normalize() method after that. 197 | pub fn (mut l Lattice) randomize(i f64) { 198 | for mut c in l.m { 199 | if c.obstacle { 200 | continue 201 | } 202 | c.randomize(i) 203 | } 204 | } 205 | 206 | // move applies simulation movements handling borders and profile collisions. 207 | // Note that the rightmost column is handled differently, and outgoing mini-particle 208 | // are re-injected on the left. 209 | pub fn (l Lattice) move(mut output Lattice) { 210 | mut index := 0 211 | output.clear() 212 | 213 | for y in 0 .. l.h { 214 | for x in 0 .. l.w { 215 | output.m[index].obstacle = l.m[index].obstacle // Copy src reachable state to output 216 | for m in vi { // For this cell, for all direction vectors or mini particles 217 | mini_part := l.m[index].get(m) 218 | if dst_ind := l.reachable(x, y, m) { 219 | output.m[dst_ind].sum(m, mini_part) // move mini-particle 220 | } else { 221 | output.m[index].sum(m.opposite(), mini_part) // rebound mini-particle, don't move but invert direction vector. 222 | } 223 | } 224 | index++ 225 | } 226 | } 227 | } 228 | 229 | // collide performs the most sensible step: Collision between mini-particles. 230 | pub fn (mut l Lattice) collide() { 231 | for mut c in l.m { 232 | if c.obstacle == false { 233 | mut new_cell := Cell.zero(false) 234 | 235 | for m in vi { 236 | f := c.get(m) 237 | feq := c.equ(m) 238 | assert math.is_nan(feq) == false 239 | assert math.is_nan(f) == false 240 | new_cell.set(m, f - ((1.0 / tau) * (f - feq))) 241 | } 242 | c = new_cell 243 | } 244 | } 245 | } 246 | 247 | // reachable test if destination Cell (base on x,y and Direction vector) 248 | // is cross-able or reachable. Lattice edge is limiting, as the profile as 249 | // well, none is returned on these case. For reachable, index of the 250 | // reachable Cell (in Lattice) is returned, for an easy update. 251 | fn (l Lattice) reachable(x int, y int, v Vi) ?int { 252 | assert x >= 0 253 | assert y >= 0 254 | 255 | // Add direction vector to current position to get destination position. 256 | mut nx := x + dvx_i[int(v)] 257 | ny := y + dvy_i[int(v)] 258 | 259 | if ny < 0 || ny >= l.h { 260 | return none 261 | } 262 | 263 | if nx < 0 { 264 | nx = nx + l.w 265 | } 266 | 267 | if nx >= l.w { 268 | nx = nx - l.w 269 | } 270 | 271 | ind := nx + (l.w * ny) // Get 1D index in lattice. 272 | 273 | return if l.m[ind].obstacle { 274 | none 275 | } else { 276 | ind // Destination cell is obstacle free. Return it's index. 277 | } 278 | } 279 | -------------------------------------------------------------------------------- /messagebox.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_messagebox.h 8 | // 9 | 10 | // MessageBoxFlags is C.SDL_MessageBoxFlags 11 | // MessageBox flags. If supported will display warning icon, etc. 12 | pub enum MessageBoxFlags { 13 | error = C.SDL_MESSAGEBOX_ERROR // 0x00000010, error dialog 14 | warning = C.SDL_MESSAGEBOX_WARNING // 0x00000020, warning dialog 15 | information = C.SDL_MESSAGEBOX_INFORMATION // 0x00000040, informational dialog 16 | buttons_left_to_right = C.SDL_MESSAGEBOX_BUTTONS_LEFT_TO_RIGHT // 0x00000080, buttons placed left to right 17 | buttons_right_to_left = C.SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT // 0x00000100, buttons placed right to left 18 | } 19 | 20 | // MessageBoxButtonFlags is C.SDL_MessageBoxButtonFlags 21 | // Flags for SDL_MessageBoxButtonData. 22 | pub enum MessageBoxButtonFlags { 23 | returnkey_default = C.SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT // 0x00000001, Marks the default button when return is hit 24 | escapekey_default = C.SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT // 0x00000002, Marks the default button when escape is hit 25 | } 26 | 27 | // MessageBoxButtonData is individual button data. 28 | @[typedef] 29 | pub struct C.SDL_MessageBoxButtonData { 30 | pub: 31 | flags u32 // ::SDL_MessageBoxButtonFlags 32 | buttonid int // User defined button id (value returned via SDL_ShowMessageBox) 33 | text &char // The UTF-8 button text 34 | } 35 | 36 | pub type MessageBoxButtonData = C.SDL_MessageBoxButtonData 37 | 38 | // MessageBoxColor is a RGB value used in a message box color scheme 39 | @[typedef] 40 | pub struct C.SDL_MessageBoxColor { 41 | pub: 42 | r u8 43 | g u8 44 | b u8 45 | } 46 | 47 | pub type MessageBoxColor = C.SDL_MessageBoxColor 48 | 49 | // MessageBoxColorType is C.SDL_MessageBoxColorType 50 | pub enum MessageBoxColorType { 51 | background = C.SDL_MESSAGEBOX_COLOR_BACKGROUND 52 | text = C.SDL_MESSAGEBOX_COLOR_TEXT 53 | button_border = C.SDL_MESSAGEBOX_COLOR_BUTTON_BORDER 54 | button_background = C.SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND 55 | button_selected = C.SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED 56 | max = C.SDL_MESSAGEBOX_COLOR_MAX 57 | } 58 | 59 | // MessageBoxColorScheme is a set of colors to use for message box dialogs 60 | @[typedef] 61 | pub struct C.SDL_MessageBoxColorScheme { 62 | pub: 63 | colors [6]MessageBoxColor 64 | } 65 | 66 | pub type MessageBoxColorScheme = C.SDL_MessageBoxColorScheme 67 | 68 | // MessageBoxData is a MessageBox structure containing title, text, window, etc. 69 | @[typedef] 70 | pub struct C.SDL_MessageBoxData { 71 | pub: 72 | flags u32 // ::SDL_MessageBoxFlags 73 | window &Window // Parent window, can be NULL 74 | title &char // UTF-8 title 75 | message &char // UTF-8 message text 76 | numbuttons int 77 | buttons &MessageBoxButtonData // C.SDL_MessageBoxButtonData 78 | colorScheme &MessageBoxColorScheme // C.SDL_MessageBoxColorScheme, ::SDL_MessageBoxColorScheme, can be NULL to use system settings 79 | } 80 | 81 | pub type MessageBoxData = C.SDL_MessageBoxData 82 | 83 | fn C.SDL_ShowMessageBox(messageboxdata &C.SDL_MessageBoxData, buttonid &int) int 84 | 85 | // show_message_box creates a modal message box. 86 | // 87 | // If your needs aren't complex, it might be easier to use 88 | // SDL_ShowSimpleMessageBox. 89 | // 90 | // This function should be called on the thread that created the parent 91 | // window, or on the main thread if the messagebox has no parent. It will 92 | // block execution of that thread until the user clicks a button or closes the 93 | // messagebox. 94 | // 95 | // This function may be called at any time, even before SDL_Init(). This makes 96 | // it useful for reporting errors like a failure to create a renderer or 97 | // OpenGL context. 98 | // 99 | // On X11, SDL rolls its own dialog box with X11 primitives instead of a 100 | // formal toolkit like GTK+ or Qt. 101 | // 102 | // Note that if SDL_Init() would fail because there isn't any available video 103 | // target, this function is likely to fail for the same reasons. If this is a 104 | // concern, check the return value from this function and fall back to writing 105 | // to stderr if you can. 106 | // 107 | // `messageboxdata` the SDL_MessageBoxData structure with title, text and 108 | // other options 109 | // `buttonid` the pointer to which user id of hit button should be copied 110 | // returns 0 on success or a negative error code on failure; call 111 | // SDL_GetError() for more information. 112 | // 113 | // NOTE This function is available since SDL 2.0.0. 114 | // 115 | // See also: SDL_ShowSimpleMessageBox 116 | pub fn show_message_box(messageboxdata &MessageBoxData, buttonid &int) int { 117 | return C.SDL_ShowMessageBox(messageboxdata, buttonid) 118 | } 119 | 120 | fn C.SDL_ShowSimpleMessageBox(flags u32, const_title &char, const_message &char, window &C.SDL_Window) int 121 | 122 | // show_simple_message_box displays a simple modal message box. 123 | // 124 | // If your needs aren't complex, this function is preferred over 125 | // SDL_ShowMessageBox. 126 | // 127 | // `flags` may be any of the following: 128 | // 129 | // - `SDL_MESSAGEBOX_ERROR`: error dialog 130 | // - `SDL_MESSAGEBOX_WARNING`: warning dialog 131 | // - `SDL_MESSAGEBOX_INFORMATION`: informational dialog 132 | // 133 | // This function should be called on the thread that created the parent 134 | // window, or on the main thread if the messagebox has no parent. It will 135 | // block execution of that thread until the user clicks a button or closes the 136 | // messagebox. 137 | // 138 | // This function may be called at any time, even before SDL_Init(). This makes 139 | // it useful for reporting errors like a failure to create a renderer or 140 | // OpenGL context. 141 | // 142 | // On X11, SDL rolls its own dialog box with X11 primitives instead of a 143 | // formal toolkit like GTK+ or Qt. 144 | // 145 | // Note that if SDL_Init() would fail because there isn't any available video 146 | // target, this function is likely to fail for the same reasons. If this is a 147 | // concern, check the return value from this function and fall back to writing 148 | // to stderr if you can. 149 | // 150 | // `flags` an SDL_MessageBoxFlags value 151 | // `title` UTF-8 title text 152 | // `message` UTF-8 message text 153 | // `window` the parent window, or NULL for no parent 154 | // returns 0 on success or a negative error code on failure; call 155 | // SDL_GetError() for more information. 156 | // 157 | // NOTE This function is available since SDL 2.0.0. 158 | // 159 | // See also: SDL_ShowMessageBox 160 | pub fn show_simple_message_box(flags u32, const_title &char, const_message &char, window &Window) int { 161 | return C.SDL_ShowSimpleMessageBox(flags, const_title, const_message, window) 162 | } 163 | -------------------------------------------------------------------------------- /system_windows.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_system.h 8 | // 9 | 10 | // Platform specific functions for Windows 11 | 12 | // WindowsMessageHook is `typedef void (SDLCALL * SDL_WindowsMessageHook)(void *userdata, void *hWnd, unsigned int message, Uint64 wParam, Sint64 lParam)` 13 | pub type WindowsMessageHook = fn (userdata voidptr, h_wnd voidptr, message u32, w_param u64, l_param i64) 14 | 15 | fn C.SDL_SetWindowsMessageHook(callback WindowsMessageHook, userdata voidptr) 16 | 17 | // set_windows_message_hook sets a callback for every Windows message, run before TranslateMessage(). 18 | // 19 | // `callback` The SDL_WindowsMessageHook function to call. 20 | // `userdata` a pointer to pass to every iteration of `callback` 21 | // 22 | // NOTE This function is available since SDL 2.0.4. 23 | pub fn set_windows_message_hook(callback WindowsMessageHook, userdata voidptr) { 24 | C.SDL_SetWindowsMessageHook(callback, userdata) 25 | } 26 | 27 | fn C.SDL_Direct3D9GetAdapterIndex(display_index int) int 28 | 29 | // direct_3d9_get_adapter_index gets the D3D9 adapter index that matches the specified display index. 30 | // 31 | // The returned adapter index can be passed to `IDirect3D9::CreateDevice` and 32 | // controls on which monitor a full screen application will appear. 33 | // 34 | // `displayIndex` the display index for which to get the D3D9 adapter 35 | // index 36 | // returns the D3D9 adapter index on success or a negative error code on 37 | // failure; call SDL_GetError() for more information. 38 | // 39 | // NOTE This function is available since SDL 2.0.1. 40 | pub fn direct_3d9_get_adapter_index(display_index int) int { 41 | return C.SDL_Direct3D9GetAdapterIndex(display_index) 42 | } 43 | 44 | @[typedef] 45 | pub struct C.IDirect3DDevice9 { 46 | } 47 | 48 | pub type IDirect3DDevice9 = C.IDirect3DDevice9 49 | 50 | fn C.SDL_RenderGetD3D9Device(renderer &C.SDL_Renderer) &C.IDirect3DDevice9 51 | 52 | // render_get_d3d9_device gets the D3D9 device associated with a renderer. 53 | // 54 | // Once you are done using the device, you should release it to avoid a 55 | // resource leak. 56 | // 57 | // `renderer` the renderer from which to get the associated D3D device 58 | // returns the D3D9 device associated with given renderer or NULL if it is 59 | // not a D3D9 renderer; call SDL_GetError() for more information. 60 | // 61 | // NOTE This function is available since SDL 2.0.1. 62 | pub fn render_get_d3d9_device(renderer &Renderer) &IDirect3DDevice9 { 63 | return C.SDL_RenderGetD3D9Device(renderer) 64 | } 65 | 66 | @[typedef] 67 | pub struct C.ID3D11Device { 68 | } 69 | 70 | pub type ID3D11Device = C.ID3D11Device 71 | 72 | fn C.SDL_RenderGetD3D11Device(renderer &C.SDL_Renderer) &C.ID3D11Device 73 | 74 | // render_get_d3_d11_device gets the D3D11 device associated with a renderer. 75 | // 76 | // Once you are done using the device, you should release it to avoid a 77 | // resource leak. 78 | // 79 | // `renderer` the renderer from which to get the associated D3D11 device 80 | // returns the D3D11 device associated with given renderer or NULL if it is 81 | // not a D3D11 renderer; call SDL_GetError() for more information. 82 | // 83 | // NOTE This function is available since SDL 2.0.16. 84 | pub fn render_get_d3_d11_device(renderer &Renderer) &ID3D11Device { 85 | return C.SDL_RenderGetD3D11Device(renderer) 86 | } 87 | 88 | @[typedef] 89 | struct C.ID3D12Device { 90 | } 91 | 92 | pub type ID3D12Device = C.ID3D12Device 93 | 94 | fn C.SDL_RenderGetD3D12Device(renderer &C.SDL_Renderer) &C.ID3D12Device 95 | 96 | // render_get_d3_d12_device gets the D3D12 device associated with a renderer. 97 | // 98 | // Once you are done using the device, you should release it to avoid a 99 | // resource leak. 100 | // 101 | // `renderer` the renderer from which to get the associated D3D12 device 102 | // returns the D3D12 device associated with given renderer or NULL if it is 103 | // not a D3D12 renderer; call SDL_GetError() for more information. 104 | // 105 | // NOTE This function is available since SDL 2.24.0. 106 | pub fn render_get_d3_d12_device(renderer &Renderer) &ID3D12Device { 107 | return C.SDL_RenderGetD3D12Device(renderer) 108 | } 109 | 110 | fn C.SDL_DXGIGetOutputInfo(display_index int, adapter_index &int, output_index &int) bool 111 | 112 | // dxgi_get_output_info gets the DXGI Adapter and Output indices for the specified display index. 113 | // 114 | // The DXGI Adapter and Output indices can be passed to `EnumAdapters` and 115 | // `EnumOutputs` respectively to get the objects required to create a DX10 or 116 | // DX11 device and swap chain. 117 | // 118 | // Before SDL 2.0.4 this function did not return a value. Since SDL 2.0.4 it 119 | // returns an SDL_bool. 120 | // 121 | // `displayIndex` the display index for which to get both indices 122 | // `adapterIndex` a pointer to be filled in with the adapter index 123 | // `outputIndex` a pointer to be filled in with the output index 124 | // returns SDL_TRUE on success or SDL_FALSE on failure; call SDL_GetError() 125 | // for more information. 126 | // 127 | // NOTE This function is available since SDL 2.0.2. 128 | pub fn dxgi_get_output_info(display_index int, adapter_index &int, output_index &int) bool { 129 | return C.SDL_DXGIGetOutputInfo(display_index, adapter_index, output_index) 130 | } 131 | 132 | /* 133 | TODO support GDK? 134 | $if gdk ? { 135 | [typedef] 136 | struct C.XTaskQueueHandle {} // XTaskQueueObject 137 | pub type XTaskQueueHandle = C.XTaskQueueHandle 138 | 139 | [typedef] 140 | struct C.XUserHandle {} // XUser 141 | pub type XUserHandle = C.XUserHandle 142 | 143 | fn C.SDL_GDKGetTaskQueue(out_task_queue &C.XTaskQueueHandle) int 144 | // gdk_get_task_queue gets a reference to the global async task queue handle for GDK, 145 | // initializing if needed. 146 | // 147 | // Once you are done with the task queue, you should call 148 | // XTaskQueueCloseHandle to reduce the reference count to avoid a resource 149 | // leak. 150 | // 151 | // `outTaskQueue` a pointer to be filled in with task queue handle. 152 | // returns 0 if success, -1 if any error occurs. 153 | // 154 | // NOTE This function is available since SDL 2.24.0. 155 | pub fn gdk_get_task_queue(out_task_queue &XTaskQueueHandle) int{ 156 | return C.SDL_GDKGetTaskQueue(out_task_queue) 157 | } 158 | 159 | fn C.SDL_GDKGetDefaultUser(XUserHandle * outUserHandle) int 160 | // Gets a reference to the default user handle for GDK. 161 | // 162 | // This is effectively a synchronous version of XUserAddAsync, which always 163 | // prefers the default user and allows a sign-in UI. 164 | // 165 | // `outUserHandle` a pointer to be filled in with the default user 166 | // handle. 167 | // returns 0 if success, -1 if any error occurs. 168 | // 169 | // NOTE This function is available since SDL 2.28.0. 170 | pub fn gdk_get_default_user(out_user_handle &XUserHandle) int { 171 | return C.SDL_GDKGetDefaultUser(out_user_handle) 172 | } 173 | } 174 | */ 175 | -------------------------------------------------------------------------------- /sdl.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL.h 8 | // 9 | 10 | pub const null = unsafe { nil } 11 | 12 | // These are the flags which may be passed to SDL_Init(). You should 13 | // specify the subsystems which you will be using in your application. 14 | pub const init_timer = u32(C.SDL_INIT_TIMER) // 0x00000001u 15 | 16 | pub const init_audio = u32(C.SDL_INIT_AUDIO) // 0x00000010u 17 | 18 | pub const init_video = u32(C.SDL_INIT_VIDEO) // 0x00000020u SDL_INIT_VIDEO implies SDL_INIT_EVENTS 19 | 20 | pub const init_joystick = u32(C.SDL_INIT_JOYSTICK) // 0x00000200u SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS 21 | 22 | pub const init_haptic = u32(C.SDL_INIT_HAPTIC) // 0x00001000u 23 | 24 | pub const init_gamecontroller = u32(C.SDL_INIT_GAMECONTROLLER) // 0x00002000u SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK 25 | 26 | pub const init_events = u32(C.SDL_INIT_EVENTS) // 0x00004000u 27 | 28 | pub const init_sensor = u32(C.SDL_INIT_SENSOR) // 0x00008000u 29 | 30 | pub const init_noparachute = u32(C.SDL_INIT_NOPARACHUTE) // 0x00100000u compatibility; this flag is ignored. 31 | 32 | pub const init_everything = u32(C.SDL_INIT_EVERYTHING) // ( SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | INIT_GAMECONTROLLER | SDL_INIT_SENSOR ) 33 | 34 | fn C.SDL_Init(flags u32) int 35 | 36 | // init initializes the SDL library. 37 | // 38 | // SDL_Init() simply forwards to calling SDL_InitSubSystem(). Therefore, the 39 | // two may be used interchangeably. Though for readability of your code 40 | // SDL_InitSubSystem() might be preferred. 41 | // 42 | // The file I/O (for example: SDL_RWFromFile) and threading (SDL_CreateThread) 43 | // subsystems are initialized by default. Message boxes 44 | // (SDL_ShowSimpleMessageBox) also attempt to work without initializing the 45 | // video subsystem, in hopes of being useful in showing an error dialog when 46 | // SDL_Init fails. You must specifically initialize other subsystems if you 47 | // use them in your application. 48 | // 49 | // Logging (such as SDL_Log) works without initialization, too. 50 | // 51 | // `flags` may be any of the following OR'd together: 52 | // 53 | // - `SDL_INIT_TIMER`: timer subsystem 54 | // - `SDL_INIT_AUDIO`: audio subsystem 55 | // - `SDL_INIT_VIDEO`: video subsystem; automatically initializes the events 56 | // subsystem 57 | // - `SDL_INIT_JOYSTICK`: joystick subsystem; automatically initializes the 58 | // events subsystem 59 | // - `SDL_INIT_HAPTIC`: haptic (force feedback) subsystem 60 | // - `SDL_INIT_GAMECONTROLLER`: controller subsystem; automatically 61 | // initializes the joystick subsystem 62 | // - `SDL_INIT_EVENTS`: events subsystem 63 | // - `SDL_INIT_EVERYTHING`: all of the above subsystems 64 | // - `SDL_INIT_NOPARACHUTE`: compatibility; this flag is ignored 65 | // 66 | // Subsystem initialization is ref-counted, you must call SDL_QuitSubSystem() 67 | // for each SDL_InitSubSystem() to correctly shutdown a subsystem manually (or 68 | // call SDL_Quit() to force shutdown). If a subsystem is already loaded then 69 | // this call will increase the ref-count and return. 70 | // 71 | // `flags` subsystem initialization flags 72 | // returns 0 on success or a negative error code on failure; call 73 | // SDL_GetError() for more information. 74 | // 75 | // NOTE This function is available since SDL 2.0.0. 76 | // 77 | // See also: SDL_InitSubSystem 78 | // See also: SDL_Quit 79 | // See also: SDL_SetMainReady 80 | // See also: SDL_WasInit 81 | pub fn init(flags u32) int { 82 | return C.SDL_Init(flags) 83 | } 84 | 85 | fn C.SDL_InitSubSystem(flags u32) int 86 | 87 | // init_sub_system is a compatibility function to initialize the SDL library. 88 | // 89 | // In SDL2, this function and SDL_Init() are interchangeable. 90 | // 91 | // `flags` any of the flags used by SDL_Init(); see SDL_Init for details. 92 | // returns 0 on success or a negative error code on failure; call 93 | // SDL_GetError() for more information. 94 | // 95 | // NOTE This function is available since SDL 2.0.0. 96 | // 97 | // See also: SDL_Init 98 | // See also: SDL_Quit 99 | // See also: SDL_QuitSubSystem 100 | pub fn init_sub_system(flags u32) int { 101 | return C.SDL_InitSubSystem(flags) 102 | } 103 | 104 | fn C.SDL_QuitSubSystem(flags u32) 105 | 106 | // quit_sub_system shuts down specific SDL subsystems. 107 | // 108 | // If you start a subsystem using a call to that subsystem's init function 109 | // (for example SDL_VideoInit()) instead of SDL_Init() or SDL_InitSubSystem(), 110 | // SDL_QuitSubSystem() and SDL_WasInit() will not work. You will need to use 111 | // that subsystem's quit function (SDL_VideoQuit()) directly instead. But 112 | // generally, you should not be using those functions directly anyhow; use 113 | // SDL_Init() instead. 114 | // 115 | // You still need to call SDL_Quit() even if you close all open subsystems 116 | // with SDL_QuitSubSystem(). 117 | // 118 | // `flags` any of the flags used by SDL_Init(); see SDL_Init for details. 119 | // 120 | // NOTE This function is available since SDL 2.0.0. 121 | // 122 | // See also: SDL_InitSubSystem 123 | // See also: SDL_Quit 124 | pub fn quit_sub_system(flags u32) { 125 | C.SDL_QuitSubSystem(flags) 126 | } 127 | 128 | fn C.SDL_WasInit(flags u32) u32 129 | 130 | // was_init gets a mask of the specified subsystems which are currently initialized. 131 | // 132 | // `flags` any of the flags used by SDL_Init(); see SDL_Init for details. 133 | // returns a mask of all initialized subsystems if `flags` is 0, otherwise it 134 | // returns the initialization status of the specified subsystems. 135 | // 136 | // The return value does not include SDL_INIT_NOPARACHUTE. 137 | // 138 | // NOTE This function is available since SDL 2.0.0. 139 | // 140 | // See also: SDL_Init 141 | // See also: SDL_InitSubSystem 142 | pub fn was_init(flags u32) u32 { 143 | return C.SDL_WasInit(flags) 144 | } 145 | 146 | fn C.SDL_Quit() 147 | 148 | // quit cleans up all initialized subsystems. 149 | // 150 | // You should call this function even if you have already shutdown each 151 | // initialized subsystem with SDL_QuitSubSystem(). It is safe to call this 152 | // function even in the case of errors in initialization. 153 | // 154 | // If you start a subsystem using a call to that subsystem's init function 155 | // (for example SDL_VideoInit()) instead of SDL_Init() or SDL_InitSubSystem(), 156 | // then you must use that subsystem's quit function (SDL_VideoQuit()) to shut 157 | // it down before calling SDL_Quit(). But generally, you should not be using 158 | // those functions directly anyhow; use SDL_Init() instead. 159 | // 160 | // You can use this function with atexit() to ensure that it is run when your 161 | // application is shutdown, but it is not wise to do this from a library or 162 | // other dynamically loaded code. 163 | // 164 | // NOTE This function is available since SDL 2.0.0. 165 | // 166 | // See also: SDL_Init 167 | // See also: SDL_QuitSubSystem 168 | pub fn quit() { 169 | C.SDL_Quit() 170 | } 171 | -------------------------------------------------------------------------------- /timer.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_timer.h 8 | // 9 | 10 | // TimerCallback is the function prototype for the timer callback function. 11 | // 12 | // The callback function is passed the current timer interval and returns 13 | // the next timer interval. If the returned value is the same as the one 14 | // passed in, the periodic alarm continues, otherwise a new alarm is 15 | // scheduled. If the callback returns 0, the periodic alarm is cancelled. 16 | pub type TimerCallback = fn (interval u32, param voidptr) u32 17 | 18 | // `typedef Uint32 (SDLCALL * SDL_TimerCallback) (Uint32 interval, void *param);` 19 | fn C.SDL_TimerCallback(interval u32, param voidptr) u32 20 | 21 | // Definition of the timer ID type. 22 | // typedef int SDL_TimerID; 23 | pub type TimerID = int 24 | 25 | fn C.SDL_GetTicks() u32 26 | 27 | // get_ticks gets the number of milliseconds since SDL library initialization. 28 | // 29 | // This value wraps if the program runs for more than ~49 days. 30 | // 31 | // This function is not recommended as of SDL 2.0.18; use SDL_GetTicks64() 32 | // instead, where the value doesn't wrap every ~49 days. There are places in 33 | // SDL where we provide a 32-bit timestamp that can not change without 34 | // breaking binary compatibility, though, so this function isn't officially 35 | // deprecated. 36 | // 37 | // returns an unsigned 32-bit value representing the number of milliseconds 38 | // since the SDL library initialized. 39 | // 40 | // NOTE This function is available since SDL 2.0.0. 41 | // 42 | // See also: SDL_TICKS_PASSED 43 | pub fn get_ticks() u32 { 44 | return C.SDL_GetTicks() 45 | } 46 | 47 | fn C.SDL_GetTicks64() u64 48 | 49 | // get_ticks64 gets the number of milliseconds since SDL library initialization. 50 | // 51 | // Note that you should not use the SDL_TICKS_PASSED macro with values 52 | // returned by this function, as that macro does clever math to compensate for 53 | // the 32-bit overflow every ~49 days that SDL_GetTicks() suffers from. 64-bit 54 | // values from this function can be safely compared directly. 55 | // 56 | // For example, if you want to wait 100 ms, you could do this: 57 | // 58 | // ```c 59 | // const Uint64 timeout = SDL_GetTicks64() + 100; 60 | // while (SDL_GetTicks64() < timeout) { 61 | // // ... do work until timeout has elapsed 62 | // } 63 | // ``` 64 | // 65 | // returns an unsigned 64-bit value representing the number of milliseconds 66 | // since the SDL library initialized. 67 | // 68 | // NOTE This function is available since SDL 2.0.18. 69 | pub fn get_ticks64() u64 { 70 | return C.SDL_GetTicks64() 71 | } 72 | 73 | fn C.SDL_TICKS_PASSED(a u32, b u32) bool 74 | 75 | // ticks_passed compares 32-bit SDL tick values, and return true if `A` has passed `B`. 76 | // 77 | // This should be used with results from SDL_GetTicks(), as this macro 78 | // attempts to deal with the 32-bit counter wrapping back to zero every ~49 79 | // days, but should _not_ be used with SDL_GetTicks64(), which does not have 80 | // that problem. 81 | // 82 | // For example, with SDL_GetTicks(), if you want to wait 100 ms, you could 83 | // do this: 84 | // 85 | /* 86 | ```c 87 | const Uint32 timeout = SDL_GetTicks() + 100; 88 | while (!SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) { 89 | // ... do work until timeout has elapsed 90 | } 91 | ``` 92 | */ 93 | // 94 | // Note that this does not handle tick differences greater 95 | // than 2^31 so take care when using the above kind of code 96 | // with large timeout delays (tens of days). 97 | pub fn ticks_passed(a u32, b u32) bool { 98 | return C.SDL_TICKS_PASSED(a, b) 99 | } 100 | 101 | fn C.SDL_GetPerformanceCounter() u64 102 | 103 | // get_performance_counter gets the current value of the high resolution counter. 104 | // 105 | // This function is typically used for profiling. 106 | // 107 | // The counter values are only meaningful relative to each other. Differences 108 | // between values can be converted to times by using 109 | // SDL_GetPerformanceFrequency(). 110 | // 111 | // returns the current counter value. 112 | // 113 | // NOTE This function is available since SDL 2.0.0. 114 | // 115 | // See also: SDL_GetPerformanceFrequency 116 | pub fn get_performance_counter() u64 { 117 | return C.SDL_GetPerformanceCounter() 118 | } 119 | 120 | fn C.SDL_GetPerformanceFrequency() u64 121 | 122 | // get_performance_frequency gets the count per second of the high resolution counter. 123 | // 124 | // returns a platform-specific count per second. 125 | // 126 | // NOTE This function is available since SDL 2.0.0. 127 | // 128 | // See also: SDL_GetPerformanceCounter 129 | pub fn get_performance_frequency() u64 { 130 | return C.SDL_GetPerformanceFrequency() 131 | } 132 | 133 | fn C.SDL_Delay(ms u32) 134 | 135 | // delay waits a specified number of milliseconds before returning. 136 | // 137 | // This function waits a specified number of milliseconds before returning. It 138 | // waits at least the specified time, but possibly longer due to OS 139 | // scheduling. 140 | // 141 | // NOTE This function is available since SDL 2.0.0. 142 | // 143 | // `ms` the number of milliseconds to delay 144 | pub fn delay(ms u32) { 145 | C.SDL_Delay(ms) 146 | } 147 | 148 | fn C.SDL_AddTimer(interval u32, callback C.SDL_TimerCallback, param voidptr) TimerID 149 | 150 | // add_timer calls a callback function at a future time. 151 | // 152 | // If you use this function, you must pass `SDL_INIT_TIMER` to SDL_Init(). 153 | // 154 | // The callback function is passed the current timer interval and the user 155 | // supplied parameter from the SDL_AddTimer() call and should return the next 156 | // timer interval. If the value returned from the callback is 0, the timer is 157 | // canceled. 158 | // 159 | // The callback is run on a separate thread. 160 | // 161 | // Timers take into account the amount of time it took to execute the 162 | // callback. For example, if the callback took 250 ms to execute and returned 163 | // 1000 (ms), the timer would only wait another 750 ms before its next 164 | // iteration. 165 | // 166 | // Timing may be inexact due to OS scheduling. Be sure to note the current 167 | // time with SDL_GetTicks() or SDL_GetPerformanceCounter() in case your 168 | // callback needs to adjust for variances. 169 | // 170 | // `interval` the timer delay, in milliseconds, passed to `callback` 171 | // `callback` the SDL_TimerCallback function to call when the specified 172 | // `interval` elapses 173 | // `param` a pointer that is passed to `callback` 174 | // returns a timer ID or 0 if an error occurs; call SDL_GetError() for more 175 | // information. 176 | // 177 | // NOTE This function is available since SDL 2.0.0. 178 | // 179 | // See also: SDL_RemoveTimer 180 | pub fn add_timer(interval u32, callback TimerCallback, param voidptr) TimerID { 181 | return int(C.SDL_AddTimer(interval, C.SDL_TimerCallback(callback), param)) 182 | } 183 | 184 | fn C.SDL_RemoveTimer(id C.SDL_TimerID) bool 185 | 186 | // remove_timer removes a timer created with SDL_AddTimer(). 187 | // 188 | // `id` the ID of the timer to remove 189 | // returns SDL_TRUE if the timer is removed or SDL_FALSE if the timer wasn't 190 | // found. 191 | // 192 | // NOTE This function is available since SDL 2.0.0. 193 | // 194 | // See also: SDL_AddTimer 195 | pub fn remove_timer(id TimerID) bool { 196 | return C.SDL_RemoveTimer(C.SDL_TimerID(id)) 197 | } 198 | -------------------------------------------------------------------------------- /vulkan/vulkan.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module vulkan 5 | 6 | import sdl 7 | 8 | // 9 | // SDL_vulkan.h 10 | // 11 | 12 | /* 13 | TODO 14 | [typedef] 15 | // C.VkInstance 16 | pub struct C.SDL_vulkanInstance { 17 | } 18 | // C.VkSurfaceKHR 19 | [typedef] 20 | pub struct C.SDL_vulkanSurface { 21 | // for compatibility with Tizen 22 | }*/ 23 | 24 | fn C.SDL_Vulkan_LoadLibrary(path &char) int 25 | 26 | // vulkan_load_library dynamically loads the Vulkan loader library. 27 | // 28 | // This should be called after initializing the video driver, but before 29 | // creating any Vulkan windows. If no Vulkan loader library is loaded, the 30 | // default library will be loaded upon creation of the first Vulkan window. 31 | // 32 | // It is fairly common for Vulkan applications to link with libvulkan instead 33 | // of explicitly loading it at run time. This will work with SDL provided the 34 | // application links to a dynamic library and both it and SDL use the same 35 | // search path. 36 | // 37 | // If you specify a non-NULL `path`, an application should retrieve all of the 38 | // Vulkan functions it uses from the dynamic library using 39 | // SDL_Vulkan_GetVkGetInstanceProcAddr unless you can guarantee `path` points 40 | // to the same vulkan loader library the application linked to. 41 | // 42 | // On Apple devices, if `path` is NULL, SDL will attempt to find the 43 | // `vkGetInstanceProcAddr` address within all the Mach-O images of the current 44 | // process. This is because it is fairly common for Vulkan applications to 45 | // link with libvulkan (and historically MoltenVK was provided as a static 46 | // library). If it is not found, on macOS, SDL will attempt to load 47 | // `vulkan.framework/vulkan`, `libvulkan.1.dylib`, 48 | // `MoltenVK.framework/MoltenVK`, and `libMoltenVK.dylib`, in that order. On 49 | // iOS, SDL will attempt to load `libMoltenVK.dylib`. Applications using a 50 | // dynamic framework or .dylib must ensure it is included in its application 51 | // bundle. 52 | // 53 | // On non-Apple devices, application linking with a static libvulkan is not 54 | // supported. Either do not link to the Vulkan loader or link to a dynamic 55 | // library version. 56 | // 57 | // `path` The platform dependent Vulkan loader library name or NULL 58 | // returns 0 on success or -1 if the library couldn't be loaded; call 59 | // SDL_GetError() for more information. 60 | // 61 | // NOTE This function is available in SDL 2.0.6 62 | // 63 | // See also: SDL_Vulkan_GetVkInstanceProcAddr 64 | // See also: SDL_Vulkan_UnloadLibrary 65 | pub fn vulkan_load_library(path &char) int { 66 | return C.SDL_Vulkan_LoadLibrary(path) 67 | } 68 | 69 | fn C.SDL_Vulkan_GetVkGetInstanceProcAddr() voidptr 70 | 71 | // vulkan_get_vk_get_instance_proc_addr gets the address of the `vkGetInstanceProcAddr` function. 72 | // 73 | // This should be called after either calling SDL_Vulkan_LoadLibrary() or 74 | // creating an SDL_Window with the `SDL_WINDOW_VULKAN` flag. 75 | // 76 | // returns the function pointer for `vkGetInstanceProcAddr` or NULL on error. 77 | // 78 | // NOTE This function is available since SDL 2.0.6. 79 | pub fn vulkan_get_vk_get_instance_proc_addr() voidptr { 80 | return C.SDL_Vulkan_GetVkGetInstanceProcAddr() 81 | } 82 | 83 | fn C.SDL_Vulkan_UnloadLibrary() 84 | 85 | // vulkan_unload_library unloads the Vulkan library previously loaded by SDL_Vulkan_LoadLibrary() 86 | // 87 | // NOTE This function is available in SDL 2.0.6 88 | // 89 | // See also: SDL_Vulkan_LoadLibrary 90 | pub fn vulkan_unload_library() { 91 | C.SDL_Vulkan_UnloadLibrary() 92 | } 93 | 94 | fn C.SDL_Vulkan_GetInstanceExtensions(window &C.SDL_Window, p_count &u32, p_names &&char) bool 95 | 96 | // vulkan_get_instance_extensions gets the names of the Vulkan instance extensions needed to create a surface 97 | // with SDL_Vulkan_CreateSurface. 98 | // 99 | // If `pNames` is NULL, then the number of required Vulkan instance extensions 100 | // is returned in `pCount`. Otherwise, `pCount` must point to a variable set 101 | // to the number of elements in the `pNames` array, and on return the variable 102 | // is overwritten with the number of names actually written to `pNames`. If 103 | // `pCount` is less than the number of required extensions, at most `pCount` 104 | // structures will be written. If `pCount` is smaller than the number of 105 | // required extensions, SDL_FALSE will be returned instead of SDL_TRUE, to 106 | // indicate that not all the required extensions were returned. 107 | // 108 | // The `window` parameter is currently needed to be valid as of SDL 2.0.8, 109 | // however, this parameter will likely be removed in future releases 110 | // 111 | // `window` A window for which the required Vulkan instance extensions 112 | // should be retrieved (will be deprecated in a future release) 113 | // `pCount` A pointer to an unsigned int corresponding to the number of 114 | // extensions to be returned 115 | // `pNames` NULL or a pointer to an array to be filled with required 116 | // Vulkan instance extensions 117 | // returns SDL_TRUE on success, SDL_FALSE on error. 118 | // 119 | // NOTE This function is available in SDL 2.0.6 120 | // 121 | // See also: SDL_Vulkan_CreateSurface 122 | pub fn vulkan_get_instance_extensions(window &sdl.Window, p_count &u32, p_names &&char) bool { 123 | return C.SDL_Vulkan_GetInstanceExtensions(window, p_count, p_names) 124 | } 125 | 126 | // vulkan_create_surface creates a Vulkan rendering surface for a window. 127 | // 128 | // The `window` must have been created with the `SDL_WINDOW_VULKAN` flag and 129 | // `instance` must have been created with extensions returned by 130 | // SDL_Vulkan_GetInstanceExtensions() enabled. 131 | // 132 | // `window` The window to which to attach the Vulkan surface 133 | // `instance` The Vulkan instance handle 134 | // `surface` A pointer to a VkSurfaceKHR handle to output the newly 135 | // created surface 136 | // returns SDL_TRUE on success, SDL_FALSE on error. 137 | // 138 | // NOTE This function is available in SDL 2.0.6 139 | // 140 | // See also: SDL_Vulkan_GetInstanceExtensions 141 | // See also: SDL_Vulkan_GetDrawableSize 142 | /* 143 | TODO 144 | fn C.SDL_Vulkan_CreateSurface(window &C.SDL_Window, instance C.VkInstance, surface &C.VkSurfaceKHR) bool 145 | pub fn vulkan_create_surface(window &Window, instance C.VkInstance, surface &C.VkSurfaceKHR) bool{ 146 | return C.SDL_Vulkan_CreateSurface(window, instance, surface) 147 | } 148 | */ 149 | 150 | fn C.SDL_Vulkan_GetDrawableSize(window &C.SDL_Window, w &int, h &int) 151 | 152 | // vulkan_get_drawable_size gets the size of the window's underlying drawable dimensions in pixels. 153 | // 154 | // This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI 155 | // drawable, i.e. the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a 156 | // platform with high-DPI support (Apple calls this "Retina"), and not 157 | // disabled by the `SDL_HINT_VIDEO_HIGHDPI_DISABLED` hint. 158 | // 159 | // `window` an SDL_Window for which the size is to be queried 160 | // `w` Pointer to the variable to write the width to or NULL 161 | // `h` Pointer to the variable to write the height to or NULL 162 | // 163 | // NOTE This function is available in SDL 2.0.6 164 | // 165 | // See also: SDL_GetWindowSize 166 | // See also: SDL_CreateWindow 167 | // See also: SDL_Vulkan_CreateSurface 168 | pub fn vulkan_get_drawable_size(window &sdl.Window, w &int, h &int) { 169 | C.SDL_Vulkan_GetDrawableSize(window, w, h) 170 | } 171 | -------------------------------------------------------------------------------- /examples/assets/images/v-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | 25 | 26 | 28 | image/svg+xml 29 | 31 | 32 | 33 | 34 | 58 | 60 | 62 | 68 | 69 | 70 | 75 | 80 | 82 | 90 | 94 | 99 | 103 | 108 | 113 | 114 | 115 | 118 | 123 | 124 | 129 | 130 | 134 | 138 | 142 | 143 | -------------------------------------------------------------------------------- /log.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // The maximum size of a log message prior to SDL 2.0.24 7 | // 8 | // As of 2.0.24 there is no limit to the length of SDL log messages. 9 | pub const max_log_message = C.SDL_MAX_LOG_MESSAGE // 4096 10 | 11 | // LogOutputFunction is the prototype for the log output function 12 | // C.SDL_LogOutputFunction 13 | // `typedef void (SDLCALL *SDL_LogOutputFunction)(void *userdata, int category, SDL_LogPriority priority, const char *message);` 14 | pub type LogOutputFunction = fn (userdata voidptr, category int, priority LogPriority, const_message &char) 15 | 16 | // LogCategory is the predefined log categories 17 | // 18 | // By default the application category is enabled at the INFO level, 19 | // the assert category is enabled at the WARN level, test is enabled 20 | // at the VERBOSE level and all other categories are enabled at the 21 | // ERROR level. 22 | // 23 | // LogCategory is C.SDL_LogCategory 24 | pub enum LogCategory { 25 | application = C.SDL_LOG_CATEGORY_APPLICATION 26 | error = C.SDL_LOG_CATEGORY_ERROR 27 | @assert = C.SDL_LOG_CATEGORY_ASSERT 28 | system = C.SDL_LOG_CATEGORY_SYSTEM 29 | audio = C.SDL_LOG_CATEGORY_AUDIO 30 | video = C.SDL_LOG_CATEGORY_VIDEO 31 | render = C.SDL_LOG_CATEGORY_RENDER 32 | input = C.SDL_LOG_CATEGORY_INPUT 33 | test = C.SDL_LOG_CATEGORY_TEST 34 | // Reserved for future SDL library use 35 | reserved1 = C.SDL_LOG_CATEGORY_RESERVED1 36 | reserved2 = C.SDL_LOG_CATEGORY_RESERVED2 37 | reserved3 = C.SDL_LOG_CATEGORY_RESERVED3 38 | reserved4 = C.SDL_LOG_CATEGORY_RESERVED4 39 | reserved5 = C.SDL_LOG_CATEGORY_RESERVED5 40 | reserved6 = C.SDL_LOG_CATEGORY_RESERVED6 41 | reserved7 = C.SDL_LOG_CATEGORY_RESERVED7 42 | reserved8 = C.SDL_LOG_CATEGORY_RESERVED8 43 | reserved9 = C.SDL_LOG_CATEGORY_RESERVED9 44 | reserved10 = C.SDL_LOG_CATEGORY_RESERVED10 45 | // Beyond this point is reserved for application use, e.g. 46 | // enum { 47 | // MYAPP_CATEGORY_AWESOME1 = SDL_LOG_CATEGORY_CUSTOM, 48 | // MYAPP_CATEGORY_AWESOME2, 49 | // MYAPP_CATEGORY_AWESOME3, 50 | // ... 51 | // }; 52 | // 53 | custom = C.SDL_LOG_CATEGORY_CUSTOM 54 | } 55 | 56 | // LogPriority is C.SDL_LogPriority 57 | pub enum LogPriority { 58 | verbose = C.SDL_LOG_PRIORITY_VERBOSE // 1 59 | debug = C.SDL_LOG_PRIORITY_DEBUG 60 | info = C.SDL_LOG_PRIORITY_INFO 61 | warn = C.SDL_LOG_PRIORITY_WARN 62 | error = C.SDL_LOG_PRIORITY_ERROR 63 | critical = C.SDL_LOG_PRIORITY_CRITICAL 64 | num_log_priorities = C.SDL_NUM_LOG_PRIORITIES 65 | } 66 | 67 | fn C.SDL_LogSetAllPriority(priority C.SDL_LogPriority) 68 | 69 | // log_set_all_priority sets the priority of all log categories. 70 | // 71 | // `priority` the SDL_LogPriority to assign 72 | // 73 | // NOTE This function is available since SDL 2.0.0. 74 | // 75 | // See also: SDL_LogSetPriority 76 | pub fn log_set_all_priority(priority LogPriority) { 77 | C.SDL_LogSetAllPriority(C.SDL_LogPriority(int(priority))) 78 | } 79 | 80 | fn C.SDL_LogSetPriority(category int, priority C.SDL_LogPriority) 81 | 82 | // log_set_priority sets the priority of a particular log category. 83 | // 84 | // `category` the category to assign a priority to 85 | // `priority` the SDL_LogPriority to assign 86 | // 87 | // NOTE This function is available since SDL 2.0.0. 88 | // 89 | // See also: SDL_LogGetPriority 90 | // See also: SDL_LogSetAllPriority 91 | pub fn log_set_priority(category int, priority LogPriority) { 92 | C.SDL_LogSetPriority(category, C.SDL_LogPriority(int(priority))) 93 | } 94 | 95 | fn C.SDL_LogGetPriority(category int) LogPriority 96 | 97 | // log_get_priority gets the priority of a particular log category. 98 | // 99 | // `category` the category to query 100 | // returns the SDL_LogPriority for the requested category 101 | // 102 | // NOTE This function is available since SDL 2.0.0. 103 | // 104 | // See also: SDL_LogSetPriority 105 | pub fn log_get_priority(category int) LogPriority { 106 | return unsafe { LogPriority(int(C.SDL_LogGetPriority(category))) } 107 | } 108 | 109 | fn C.SDL_LogResetPriorities() 110 | 111 | // log_reset_priorities resets all priorities to default. 112 | // 113 | // This is called by SDL_Quit(). 114 | // 115 | // NOTE This function is available since SDL 2.0.0. 116 | // 117 | // See also: SDL_LogSetAllPriority 118 | // See also: SDL_LogSetPriority 119 | pub fn log_reset_priorities() { 120 | C.SDL_LogResetPriorities() 121 | } 122 | 123 | // Skipped: 124 | // extern DECLSPEC void SDLCALL SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); 125 | // extern DECLSPEC void SDLCALL SDL_LogVerbose(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); 126 | // extern DECLSPEC void SDLCALL SDL_LogDebug(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); 127 | // extern DECLSPEC void SDLCALL SDL_LogInfo(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); 128 | // extern DECLSPEC void SDLCALL SDL_LogWarn(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); 129 | // extern DECLSPEC void SDLCALL SDL_LogError(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); 130 | // extern DECLSPEC void SDLCALL SDL_LogCritical(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); 131 | // extern DECLSPEC void SDLCALL SDL_LogMessage(int category, SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(3); 132 | 133 | fn C.SDL_LogMessageV(category int, priority C.SDL_LogPriority, const_fmt &char, ap C.va_list) 134 | 135 | // log_message_v logs a message with the specified category and priority. 136 | // 137 | // `category` the category of the message 138 | // `priority` the priority of the message 139 | // `fmt` a printf() style message format string 140 | // `ap` a variable argument list 141 | // 142 | // NOTE This function is available since SDL 2.0.0. 143 | // 144 | // See also: SDL_Log 145 | // See also: SDL_LogCritical 146 | // See also: SDL_LogDebug 147 | // See also: SDL_LogError 148 | // See also: SDL_LogInfo 149 | // See also: SDL_LogMessage 150 | // See also: SDL_LogVerbose 151 | // See also: SDL_LogWarn 152 | pub fn log_message_v(category int, priority LogPriority, const_fmt &char, ap C.va_list) { 153 | C.SDL_LogMessageV(category, C.SDL_LogPriority(priority), const_fmt, ap) 154 | } 155 | 156 | fn C.SDL_LogGetOutputFunction(callback &LogOutputFunction, userdata voidptr) 157 | 158 | // log_get_output_function gets the current log output function. 159 | // 160 | // `callback` an SDL_LogOutputFunction filled in with the current log 161 | // callback 162 | // `userdata` a pointer filled in with the pointer that is passed to 163 | // `callback` 164 | // 165 | // NOTE This function is available since SDL 2.0.0. 166 | // 167 | // See also: SDL_LogSetOutputFunction 168 | // NOTE `userdata` is `**` 169 | pub fn log_get_output_function(callback &LogOutputFunction, userdata voidptr) { 170 | C.SDL_LogGetOutputFunction(callback, userdata) 171 | } 172 | 173 | fn C.SDL_LogSetOutputFunction(callback LogOutputFunction, userdata voidptr) 174 | 175 | // log_set_output_function replaces the default log output function with one of your own. 176 | // 177 | // `callback` an SDL_LogOutputFunction to call instead of the default 178 | // `userdata` a pointer that is passed to `callback` 179 | // 180 | // NOTE This function is available since SDL 2.0.0. 181 | // 182 | // See also: SDL_LogGetOutputFunction 183 | pub fn log_set_output_function(callback LogOutputFunction, userdata voidptr) { 184 | C.SDL_LogSetOutputFunction(callback, userdata) 185 | } 186 | -------------------------------------------------------------------------------- /blendmode.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_blendmode.h 8 | // 9 | 10 | // BlendMode is the blend mode used in SDL_RenderCopy() and drawing operations. 11 | // BlendMode is SDL_BlendMode 12 | pub enum BlendMode { 13 | @none = C.SDL_BLENDMODE_NONE // 0x00000000, no blending dstRGBA = srcRGBA 14 | blend = C.SDL_BLENDMODE_BLEND // 0x00000001, alpha blending dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA)) dstA = srcA + (dstA * (1-srcA)) 15 | add = C.SDL_BLENDMODE_ADD // 0x00000002, additive blending dstRGB = (srcRGB * srcA) + dstRGB dstA = dstA 16 | mod = C.SDL_BLENDMODE_MOD // 0x00000004, color modulate dstRGB = srcRGB * dstRGB dstA = dstA 17 | mul = C.SDL_BLENDMODE_MUL // 0x00000008, color multiply dstRGB = (srcRGB * dstRGB) + (dstRGB * (1-srcA)) dstA = dstA 18 | invalid = C.SDL_BLENDMODE_INVALID // 0x7FFFFFFF 19 | } 20 | 21 | // BlendOperation is the blend operation used when combining source and destination pixel components 22 | // BlendOperation is C.SDL_BlendOperation 23 | pub enum BlendOperation { 24 | add = C.SDL_BLENDOPERATION_ADD // 0x1, dst + src: supported by all renderers 25 | subtract = C.SDL_BLENDOPERATION_SUBTRACT // 0x2, src - dst : supported by D3D9, D3D11, OpenGL, OpenGLES 26 | rev_subtract = C.SDL_BLENDOPERATION_REV_SUBTRACT // 0x3, dst - src : supported by D3D9, D3D11, OpenGL, OpenGLES 27 | minimum = C.SDL_BLENDOPERATION_MINIMUM // 0x4, min(dst, src) : supported by D3D9, D3D11 28 | maximum = C.SDL_BLENDOPERATION_MAXIMUM // 0x5 max(dst, src) : supported by D3D9, D3D11 29 | } 30 | 31 | // BlendFactor is the normalized factor used to multiply pixel components 32 | // BlendFactor is C.SDL_BlendFactor 33 | pub enum BlendFactor { 34 | zero = C.SDL_BLENDFACTOR_ZERO // 0x1, 0, 0, 0, 0 35 | one = C.SDL_BLENDFACTOR_ONE // 0x2, 1, 1, 1, 1 36 | src_color = C.SDL_BLENDFACTOR_SRC_COLOR // 0x3, srcR, srcG, srcB, srcA 37 | one_minus_src_color = C.SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR // 0x4, 1-srcR, 1-srcG, 1-srcB, 1-srcA 38 | src_alpha = C.SDL_BLENDFACTOR_SRC_ALPHA // 0x5, srcA, srcA, srcA, srcA 39 | one_minus_src_alpha = C.SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA // 0x6, 1-srcA, 1-srcA, 1-srcA, 1-srcA 40 | dst_color = C.SDL_BLENDFACTOR_DST_COLOR // 0x7, dstR, dstG, dstB, dstA 41 | one_minus_dst_color = C.SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR // 0x8, 1-dstR, 1-dstG, 1-dstB, 1-dstA 42 | dst_alpha = C.SDL_BLENDFACTOR_DST_ALPHA // 0x9, dstA, dstA, dstA, dstA 43 | one_minus_dst_alpha = C.SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA // 0xA, 1-dstA, 1-dstA, 1-dstA, 1-dstA 44 | } 45 | 46 | fn C.SDL_ComposeCustomBlendMode(src_color_factor C.SDL_BlendFactor, dst_color_factor C.SDL_BlendFactor, color_operation C.SDL_BlendOperation, src_alpha_factor C.SDL_BlendFactor, dst_alpha_factor C.SDL_BlendFactor, alpha_operation C.SDL_BlendOperation) BlendMode 47 | 48 | // compose_custom_blend_mode composes a custom blend mode for renderers. 49 | // 50 | // The functions SDL_SetRenderDrawBlendMode and SDL_SetTextureBlendMode accept 51 | // the SDL_BlendMode returned by this function if the renderer supports it. 52 | // 53 | // A blend mode controls how the pixels from a drawing operation (source) get 54 | // combined with the pixels from the render target (destination). First, the 55 | // components of the source and destination pixels get multiplied with their 56 | // blend factors. Then, the blend operation takes the two products and 57 | // calculates the result that will get stored in the render target. 58 | // 59 | // Expressed in pseudocode, it would look like this: 60 | // 61 | /* 62 | ```c 63 | dstRGB = colorOperation(srcRGB * srcColorFactor, dstRGB * dstColorFactor); 64 | dstA = alphaOperation(srcA * srcAlphaFactor, dstA * dstAlphaFactor); 65 | ``` 66 | */ 67 | // 68 | // Where the functions `colorOperation(src, dst)` and `alphaOperation(src, 69 | // dst)` can return one of the following: 70 | // 71 | // - `src + dst` 72 | // - `src - dst` 73 | // - `dst - src` 74 | // - `min(src, dst)` 75 | // - `max(src, dst)` 76 | // 77 | // The red, green, and blue components are always multiplied with the first, 78 | // second, and third components of the SDL_BlendFactor, respectively. The 79 | // fourth component is not used. 80 | // 81 | // The alpha component is always multiplied with the fourth component of the 82 | // SDL_BlendFactor. The other components are not used in the alpha 83 | // calculation. 84 | // 85 | // Support for these blend modes varies for each renderer. To check if a 86 | // specific SDL_BlendMode is supported, create a renderer and pass it to 87 | // either SDL_SetRenderDrawBlendMode or SDL_SetTextureBlendMode. They will 88 | // return with an error if the blend mode is not supported. 89 | // 90 | // This list describes the support of custom blend modes for each renderer in 91 | // SDL 2.0.6. All renderers support the four blend modes listed in the 92 | // SDL_BlendMode enumeration. 93 | // 94 | // - **direct3d**: Supports all operations with all factors. However, some 95 | // factors produce unexpected results with `SDL_BLENDOPERATION_MINIMUM` and 96 | // `SDL_BLENDOPERATION_MAXIMUM`. 97 | // - **direct3d11**: Same as Direct3D 9. 98 | // - **opengl**: Supports the `SDL_BLENDOPERATION_ADD` operation with all 99 | // factors. OpenGL versions 1.1, 1.2, and 1.3 do not work correctly with SDL 100 | // 2.0.6. 101 | // - **opengles**: Supports the `SDL_BLENDOPERATION_ADD` operation with all 102 | // factors. Color and alpha factors need to be the same. OpenGL ES 1 103 | // implementation specific: May also support `SDL_BLENDOPERATION_SUBTRACT` 104 | // and `SDL_BLENDOPERATION_REV_SUBTRACT`. May support color and alpha 105 | // operations being different from each other. May support color and alpha 106 | // factors being different from each other. 107 | // - **opengles2**: Supports the `SDL_BLENDOPERATION_ADD`, 108 | // `SDL_BLENDOPERATION_SUBTRACT`, `SDL_BLENDOPERATION_REV_SUBTRACT` 109 | // operations with all factors. 110 | // - **psp**: No custom blend mode support. 111 | // - **software**: No custom blend mode support. 112 | // 113 | // Some renderers do not provide an alpha component for the default render 114 | // target. The `SDL_BLENDFACTOR_DST_ALPHA` and 115 | // `SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA` factors do not have an effect in this 116 | // case. 117 | // 118 | // `srcColorFactor` the SDL_BlendFactor applied to the red, green, and 119 | // blue components of the source pixels 120 | // `dstColorFactor` the SDL_BlendFactor applied to the red, green, and 121 | // blue components of the destination pixels 122 | // `colorOperation` the SDL_BlendOperation used to combine the red, 123 | // green, and blue components of the source and 124 | // destination pixels 125 | // `srcAlphaFactor` the SDL_BlendFactor applied to the alpha component of 126 | // the source pixels 127 | // `dstAlphaFactor` the SDL_BlendFactor applied to the alpha component of 128 | // the destination pixels 129 | // `alphaOperation` the SDL_BlendOperation used to combine the alpha 130 | // component of the source and destination pixels 131 | // returns an SDL_BlendMode that represents the chosen factors and 132 | // operations. 133 | // 134 | // NOTE This function is available since SDL 2.0.6. 135 | // 136 | // See also: SDL_SetRenderDrawBlendMode 137 | // See also: SDL_GetRenderDrawBlendMode 138 | // See also: SDL_SetTextureBlendMode 139 | // See also: SDL_GetTextureBlendMode 140 | pub fn compose_custom_blend_mode(src_color_factor BlendFactor, dst_color_factor BlendFactor, color_operation BlendOperation, src_alpha_factor BlendFactor, dst_alpha_factor BlendFactor, alpha_operation BlendOperation) BlendMode { 141 | return unsafe { 142 | BlendMode(int(C.SDL_ComposeCustomBlendMode(C.SDL_BlendFactor(src_color_factor), 143 | C.SDL_BlendFactor(dst_color_factor), C.SDL_BlendOperation(color_operation), 144 | C.SDL_BlendFactor(src_alpha_factor), C.SDL_BlendFactor(dst_alpha_factor), 145 | C.SDL_BlendOperation(alpha_operation)))) 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /examples/basic_mixer/basic_mixer.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2022 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | // 5 | // Creates a window through SDL2 and load test sounds into memory, 6 | // and play them back in a loop on finger tab or mouse click (left/right cycles back and forth). 7 | // sound_01.wav - is a range copied from https://freesound.org/people/Erokia/sounds/414245 by Eroika and is licensed under the Attribution 4.0 License. 8 | // sound_02.mp3 - is a range copied from https://freesound.org/people/haldigital97/sounds/241824 and is in the public domain. 9 | // sound_03.flac - is a range copied from https://freesound.org/people/taavhaap/sounds/528661 by taavhaap and is licensed under the Attribution 3.0 License. 10 | // sound_04.ogg - is a range copied from https://freesound.org/people/ShortRecord/sounds/575382 by ShortRecord and is licensed under the Creative Commons 0 License. 11 | // TwintrisThosenine.mod - for info see examples/tvintris/README.md 12 | // IcyGarden.mid - is downloaded from https://opengameart.org/content/original-midi-album by "Roppy Chop Studios" and is licensed under the CC0 / in the public domain. 13 | module main 14 | 15 | import os 16 | import sdl 17 | import sdl.mixer 18 | 19 | const wav_sound = 'sounds/sound_01.wav' 20 | const sounds = ['sounds/sound_02.mp3', 'sounds/sound_03.flac', 'sounds/sound_04.ogg', 21 | 'sounds/TwintrisThosenine.mod', 'sounds/IcyGarden.mid'] 22 | 23 | struct PlayCycle { 24 | pub mut: 25 | cycle int 26 | music map[string]&mixer.Music 27 | } 28 | 29 | fn (mut pc PlayCycle) next() { 30 | pc.cycle++ 31 | music_keys := pc.music.keys() 32 | if pc.cycle > music_keys.len { 33 | pc.cycle = 0 34 | } 35 | if pc.cycle == 0 { 36 | mixer.halt_music() 37 | return 38 | } 39 | music_key := music_keys[pc.cycle - 1] 40 | music := pc.music[music_key] or { panic('Music sound "${music_key}" could not be found') } 41 | if mixer.play_music(music, -1) == -1 { 42 | mixer.free_music(music) 43 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 44 | panic('Music sound "${music_key}" could not be played: ${error_msg}') 45 | } 46 | println('Playing "${music_key}"') 47 | } 48 | 49 | fn (mut pc PlayCycle) previous() { 50 | pc.cycle-- 51 | music_keys := pc.music.keys() 52 | if pc.cycle == 0 { 53 | mixer.halt_music() 54 | return 55 | } 56 | if pc.cycle < 0 { 57 | pc.cycle = music_keys.len 58 | } 59 | music_key := music_keys[pc.cycle - 1] 60 | music := pc.music[music_key] or { panic('Music sound "${music_key}" could not be found') } 61 | if mixer.play_music(music, -1) == -1 { 62 | mixer.free_music(music) 63 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 64 | panic('Music sound "${music_key}" could not be played: ${error_msg}') 65 | } 66 | println('Playing "${music_key}"') 67 | } 68 | 69 | fn get_asset_path(path string) string { 70 | $if android { 71 | return path 72 | } $else { 73 | return os.resource_abs_path(os.join_path('..', 'assets', path)) 74 | } 75 | } 76 | 77 | fn load_wav(path string) !&mixer.Chunk { 78 | asset_path := get_asset_path(path) 79 | rw := sdl.rw_from_file(asset_path.str, 'rb'.str) 80 | if rw == sdl.null { 81 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 82 | return error('Could not create wav "${path}" RW from mem data: ${error_msg}') 83 | } 84 | wav := mixer.load_wav_rw(rw, 1) 85 | if wav == sdl.null { 86 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 87 | return error('Could not load wav RW "${path}" data: ${error_msg}') 88 | } 89 | return wav 90 | } 91 | 92 | fn load_mus(path string) !&mixer.Music { 93 | asset_path := get_asset_path(path) 94 | rw := sdl.rw_from_file(asset_path.str, 'rb'.str) 95 | if rw == sdl.null { 96 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 97 | return error('Could not create music "${path}" RW from mem data: ${error_msg}') 98 | } 99 | mus := mixer.load_mus_rw(rw, 1) 100 | if mus == sdl.null { 101 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 102 | return error('Could not load music RW "${path}" data: ${error_msg}') 103 | } 104 | return mus 105 | } 106 | 107 | // [console] is needed on Windows to keep the terminal open 108 | // after launch - so people can see the output we write in it. 109 | // We output to terminal to prevent depending on e.g. sdl.tff, in case 110 | // it doesn't work or is broken - it then become easier to 111 | // diagnose any potential library problems a setup might have. 112 | @[console] 113 | fn main() { 114 | println('Const version ${mixer.major_version}.${mixer.minor_version}.${mixer.patchlevel}') 115 | mut compiled_version := sdl.Version{} 116 | mixer.mixer_version(&compiled_version) 117 | println('Compiled against version ${compiled_version.str()}') 118 | linked_version := mixer.linked_version() 119 | println('Runtime loaded version ${linked_version.major}.${linked_version.minor}.${linked_version.patch}') 120 | 121 | $if debug ? { 122 | // SDL debug info, must be called before sdl.init 123 | sdl.log_set_all_priority(sdl.LogPriority.debug) 124 | } 125 | if sdl.init(sdl.init_video | sdl.init_audio) < 0 { 126 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 127 | panic('Could not initialize SDL: ${error_msg}') 128 | } 129 | 130 | // Initialize SDL2_mixer 131 | if mixer.open_audio(u16(mixer.default_frequency), u16(mixer.default_format), u16(mixer.default_channels), 132 | 4096) < 0 { 133 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 134 | panic('Could not initialize SDL mixer: ${error_msg}') 135 | } 136 | 137 | window := sdl.create_window('Hello SDL2_mixer (Press SPACE to pause/play)'.str, 300, 138 | 300, 500, 300, 0) 139 | if window == sdl.null { 140 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 141 | panic('Could not create SDL window: ${error_msg}') 142 | } 143 | renderer := sdl.create_renderer(window, -1, u32(sdl.RendererFlags.accelerated) | u32(sdl.RendererFlags.presentvsync)) 144 | if renderer == sdl.null { 145 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 146 | panic('Could not create SDL renderer: ${error_msg}') 147 | } 148 | 149 | // Print info to terminal 150 | println('Mouse click in the window to play the next sound. 151 | On mobile you can tap the window to play the next sound. 152 | Pressing SPACE will pause/resume all sound(s). 153 | Use right/left arrow keys to go to next/previous sound.') 154 | 155 | // Load .WAV sound 156 | wav := load_wav(wav_sound) or { panic(err) } 157 | 158 | // Play WAV sound in a loop 159 | if mixer.play_channel(-1, wav, -1) < 0 { 160 | mixer.free_chunk(wav) 161 | error_msg := unsafe { cstring_to_vstring(sdl.get_error()) } 162 | panic('WAV sound could not be played: ${error_msg}') 163 | } 164 | println('Playing "${wav_sound}" (background loop)') 165 | 166 | mut pc := PlayCycle{} 167 | for sound in sounds { 168 | pc.music[sound] = load_mus(sound) or { 169 | eprintln('Loading of file ${sound} failed: ${err.msg()}') 170 | continue 171 | } 172 | } 173 | 174 | mut should_close := false 175 | for { 176 | evt := sdl.Event{} 177 | for 0 < sdl.poll_event(&evt) { 178 | match evt.@type { 179 | .quit { 180 | should_close = true 181 | } 182 | .mousebuttondown { 183 | pc.next() 184 | } 185 | .keydown { 186 | key := unsafe { sdl.KeyCode(evt.key.keysym.sym) } 187 | match key { 188 | .escape { 189 | should_close = true 190 | break 191 | } 192 | .space { 193 | if mixer.paused(-1) > 0 { 194 | mixer.resume(-1) 195 | } else { 196 | mixer.pause(-1) 197 | } 198 | } 199 | .right { 200 | pc.next() 201 | } 202 | .left { 203 | pc.previous() 204 | } 205 | else {} 206 | } 207 | } 208 | else {} 209 | } 210 | } 211 | if should_close { 212 | break 213 | } 214 | 215 | sdl.set_render_draw_color(renderer, 55, 55, 255, 255) 216 | sdl.render_clear(renderer) 217 | sdl.render_present(renderer) 218 | } 219 | 220 | sdl.destroy_renderer(renderer) 221 | sdl.destroy_window(window) 222 | mixer.close_audio() 223 | // Clean up audio 224 | mixer.free_chunk(wav) 225 | for _, v in pc.music { 226 | mixer.free_music(v) 227 | } 228 | 229 | sdl.quit() 230 | } 231 | -------------------------------------------------------------------------------- /system_android_outside_termux.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module sdl 5 | 6 | // 7 | // SDL_system.h 8 | // 9 | 10 | fn C.SDL_AndroidGetJNIEnv() voidptr 11 | 12 | // android_get_jni_env gets the Android Java Native Interface Environment of the current thread. 13 | // 14 | // This is the JNIEnv one needs to access the Java virtual machine from native 15 | // code, and is needed for many Android APIs to be usable from C. 16 | // 17 | // The prototype of the function in SDL's code actually declare a void* return 18 | // type, even if the implementation returns a pointer to a JNIEnv. The 19 | // rationale being that the SDL headers can avoid including jni.h. 20 | // 21 | // returns a pointer to Java native interface object (JNIEnv) to which the 22 | // current thread is attached, or 0 on error. 23 | // 24 | // NOTE This function is available since SDL 2.0.0. 25 | // 26 | // See also: SDL_AndroidGetActivity 27 | pub fn android_get_jni_env() voidptr { 28 | return C.SDL_AndroidGetJNIEnv() 29 | } 30 | 31 | fn C.SDL_AndroidGetActivity() voidptr 32 | 33 | // android_get_activity retrieves the Java instance of the Android activity class. 34 | // 35 | // The prototype of the function in SDL's code actually declares a void* 36 | // return type, even if the implementation returns a jobject. The rationale 37 | // being that the SDL headers can avoid including jni.h. 38 | // 39 | // The jobject returned by the function is a local reference and must be 40 | // released by the caller. See the PushLocalFrame() and PopLocalFrame() or 41 | // DeleteLocalRef() functions of the Java native interface: 42 | // 43 | // https://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html 44 | // 45 | // returns the jobject representing the instance of the Activity class of the 46 | // Android application, or NULL on error. 47 | // 48 | // NOTE This function is available since SDL 2.0.0. 49 | // 50 | // See also: SDL_AndroidGetJNIEnv 51 | pub fn android_get_activity() voidptr { 52 | return C.SDL_AndroidGetActivity() 53 | } 54 | 55 | fn C.SDL_GetAndroidSDKVersion() int 56 | 57 | // get_android_sdk_version queries Android API level of the current device. 58 | // 59 | // - API level 31: Android 12 60 | // - API level 30: Android 11 61 | // - API level 29: Android 10 62 | // - API level 28: Android 9 63 | // - API level 27: Android 8.1 64 | // - API level 26: Android 8.0 65 | // - API level 25: Android 7.1 66 | // - API level 24: Android 7.0 67 | // - API level 23: Android 6.0 68 | // - API level 22: Android 5.1 69 | // - API level 21: Android 5.0 70 | // - API level 20: Android 4.4W 71 | // - API level 19: Android 4.4 72 | // - API level 18: Android 4.3 73 | // - API level 17: Android 4.2 74 | // - API level 16: Android 4.1 75 | // - API level 15: Android 4.0.3 76 | // - API level 14: Android 4.0 77 | // - API level 13: Android 3.2 78 | // - API level 12: Android 3.1 79 | // - API level 11: Android 3.0 80 | // - API level 10: Android 2.3.3 81 | // 82 | // returns the Android API level. 83 | // 84 | // NOTE This function is available since SDL 2.0.12. 85 | pub fn get_android_sdk_version() int { 86 | return C.SDL_GetAndroidSDKVersion() 87 | } 88 | 89 | fn C.SDL_IsAndroidTV() bool 90 | 91 | // is_android_tv queries if the application is running on Android TV. 92 | // 93 | // returns SDL_TRUE if this is Android TV, SDL_FALSE otherwise. 94 | // 95 | // NOTE This function is available since SDL 2.0.8. 96 | pub fn is_android_tv() bool { 97 | return C.SDL_IsAndroidTV() 98 | } 99 | 100 | fn C.SDL_IsChromebook() bool 101 | 102 | // is_chromebook queries if the application is running on a Chromebook. 103 | // 104 | // returns SDL_TRUE if this is a Chromebook, SDL_FALSE otherwise. 105 | // 106 | // NOTE This function is available since SDL 2.0.9. 107 | pub fn is_chromebook() bool { 108 | return C.SDL_IsChromebook() 109 | } 110 | 111 | fn C.SDL_IsDeXMode() bool 112 | 113 | // is_dex_mode queries if the application is running on a Samsung DeX docking station. 114 | // 115 | // returns SDL_TRUE if this is a DeX docking station, SDL_FALSE otherwise. 116 | // 117 | // NOTE This function is available since SDL 2.0.9. 118 | pub fn is_dex_mode() bool { 119 | return C.SDL_IsDeXMode() 120 | } 121 | 122 | fn C.SDL_AndroidBackButton() 123 | 124 | // android_back_button triggers the Android system back button behavior. 125 | // 126 | // NOTE This function is available since SDL 2.0.9. 127 | pub fn android_back_button() { 128 | C.SDL_AndroidBackButton() 129 | } 130 | 131 | // See the official Android developer guide for more information: 132 | // http://developer.android.com/guide/topics/data/data-storage.html 133 | pub const android_external_storage_read = C.SDL_ANDROID_EXTERNAL_STORAGE_READ // 0x01 134 | 135 | pub const android_external_storage_write = C.SDL_ANDROID_EXTERNAL_STORAGE_WRITE // 0x02 136 | 137 | fn C.SDL_AndroidGetInternalStoragePath() &char 138 | 139 | // android_get_internal_storage_path gets the path used for internal storage for this application. 140 | // 141 | // This path is unique to your application and cannot be written to by other 142 | // applications. 143 | // 144 | // Your internal storage path is typically: 145 | // `/data/data/your.app.package/files`. 146 | // 147 | // returns the path used for internal storage or NULL on failure; call 148 | // SDL_GetError() for more information. 149 | // 150 | // NOTE This function is available since SDL 2.0.0. 151 | // 152 | // See also: SDL_AndroidGetExternalStorageState 153 | pub fn android_get_internal_storage_path() &char { 154 | return C.SDL_AndroidGetInternalStoragePath() 155 | } 156 | 157 | fn C.SDL_AndroidGetExternalStorageState() int 158 | 159 | // android_get_external_storage_state gets the current state of external storage. 160 | // 161 | // The current state of external storage, a bitmask of these values: 162 | // `SDL_ANDROID_EXTERNAL_STORAGE_READ`, `SDL_ANDROID_EXTERNAL_STORAGE_WRITE`. 163 | // 164 | // If external storage is currently unavailable, this will return 0. 165 | // 166 | // returns the current state of external storage on success or 0 on failure; 167 | // call SDL_GetError() for more information. 168 | // 169 | // NOTE This function is available since SDL 2.0.0. 170 | // 171 | // See also: SDL_AndroidGetExternalStoragePath 172 | pub fn android_get_external_storage_state() int { 173 | return C.SDL_AndroidGetExternalStorageState() 174 | } 175 | 176 | fn C.SDL_AndroidGetExternalStoragePath() &char 177 | 178 | // android_get_external_storage_path gets the path used for external storage for this application. 179 | // 180 | // This path is unique to your application, but is public and can be written 181 | // to by other applications. 182 | // 183 | // Your external storage path is typically: 184 | // `/storage/sdcard0/Android/data/your.app.package/files`. 185 | // 186 | // returns the path used for external storage for this application on success 187 | // or NULL on failure; call SDL_GetError() for more information. 188 | // 189 | // NOTE This function is available since SDL 2.0.0. 190 | // 191 | // See also: SDL_AndroidGetExternalStorageState 192 | pub fn android_get_external_storage_path() &char { 193 | return C.SDL_AndroidGetExternalStoragePath() 194 | } 195 | 196 | fn C.SDL_AndroidRequestPermission(permission &char) bool 197 | 198 | // android_request_permission requests permissions at runtime. 199 | // 200 | // This blocks the calling thread until the permission is granted or denied. 201 | // 202 | // `permission` The permission to request. 203 | // returns SDL_TRUE if the permission was granted, SDL_FALSE otherwise. 204 | // 205 | // NOTE This function is available since SDL 2.0.14. 206 | pub fn android_request_permission(permission &char) bool { 207 | return C.SDL_AndroidRequestPermission(permission) 208 | } 209 | 210 | fn C.SDL_AndroidShowToast(const_message &char, duration int, gravity int, xoffset int, yoffset int) int 211 | 212 | // android_show_toast shows an Android toast notification. 213 | // 214 | // Toasts are a sort of lightweight notification that are unique to Android. 215 | // 216 | // https://developer.android.com/guide/topics/ui/notifiers/toasts 217 | // 218 | // Shows toast in UI thread. 219 | // 220 | // For the `gravity` parameter, choose a value from here, or -1 if you don't 221 | // have a preference: 222 | // 223 | // https://developer.android.com/reference/android/view/Gravity 224 | // 225 | // `message` text message to be shown 226 | // `duration` 0=short, 1=long 227 | // `gravity` where the notification should appear on the screen. 228 | // `xoffset` set this parameter only when gravity >=0 229 | // `yoffset` set this parameter only when gravity >=0 230 | // returns 0 if success, -1 if any error occurs. 231 | // 232 | // NOTE This function is available since SDL 2.0.16. 233 | pub fn android_show_toast(const_message &char, duration int, gravity int, xoffset int, yoffset int) int { 234 | return C.SDL_AndroidShowToast(const_message, duration, gravity, xoffset, yoffset) 235 | } 236 | 237 | fn C.SDL_AndroidSendMessage(command u32, param int) int 238 | 239 | // android_send_message sends a user command to SDLActivity. 240 | // 241 | // Override "boolean onUnhandledMessage(Message msg)" to handle the message. 242 | // 243 | // `command` user command that must be greater or equal to 0x8000 244 | // `param` user parameter 245 | // 246 | // NOTE This function is available since SDL 2.0.22. 247 | pub fn android_send_message(command u32, param int) int { 248 | return C.SDL_AndroidSendMessage(command, param) 249 | } 250 | -------------------------------------------------------------------------------- /examples/lbm/main.v: -------------------------------------------------------------------------------- 1 | /** 2 | This program is about D2Q9 Lattice Boltzmann Method: 3 | See : https://en.wikipedia.org/wiki/Lattice_Boltzmann_methods 4 | 5 | It's a pet project in order to use V language: https://vlang.io/ 6 | 7 | The simulation is single threaded, probably buggy and should not be used 8 | for serious things. It's very sensible to tau parameter that should be 9 | carefully set. This parameter is related to fluid viscosity, and is set so 10 | that the fluid speed doesn't exceed a speed limit that breaks simulation. 11 | Too narrow passage (speed increased) may reach this limit. 12 | 13 | profiles files MUST be of the same size of defined width and weight and 14 | should be 8bits per pixels. Every non zero value is considered as an 15 | obstacle. 16 | 17 | to compile the program from within source directory: 18 | 19 | v -prod . 20 | 21 | or if you want gcc as compiler: 22 | 23 | v -prod -cc gcc . 24 | 25 | SDL module must be installed: https://vpm.vlang.io/packages/sdl 26 | and post install script executed, see link. 27 | 28 | The simulation is quite slow, but would you like to slow it down, just 29 | uncomment the sdl.delay(...) in file. 30 | 31 | 32 | 33 | This program is released under MIT license. 34 | */ 35 | module main 36 | 37 | import sdl 38 | import sdl.image as img 39 | import os 40 | import time 41 | 42 | const tau = 0.6 // Relaxation time, related to fluid viscosity. 43 | const rho0 = 32.0 // Average normalised density. 44 | const width = 512 45 | const height = 128 46 | const len_in_bytes = width * height * sizeof(u32) 47 | const obstacle_color = u32(0xFF004000) 48 | const low_color = u32(0xFFFFFF00) 49 | const middle_color = u32(0xFF000000) 50 | const high_color = u32(0xFF00FFFF) 51 | 52 | // Type for rendering methods, used as parameter. 53 | type Renderer = fn (l Lattice, cm []u32, mut output []u32) 54 | 55 | const renderers = [vorticity, v_speed, h_speed, densities] 56 | const renderers_names = ['vorticity', 'vertical speed', 'horizontal speed', 'density'] 57 | 58 | fn main() { 59 | argv := os.args.len 60 | 61 | if argv != 2 { 62 | println('Usage: lbm profile_file.png') 63 | println(' e.g: ./lbm profiles/circle.png') 64 | println('During simulation press "v" to show different parameters.') 65 | return 66 | } 67 | 68 | if sdl.init(sdl.init_video) < 0 { 69 | eprintln('sdl.init() error: ${unsafe { cstring_to_vstring(sdl.get_error()) }}') 70 | return 71 | } 72 | 73 | flags := u32(sdl.WindowFlags.opengl) | u32(sdl.WindowFlags.resizable) 74 | window := sdl.create_window(c'Lattice Boltzmann Method [D2Q9]', sdl.windowpos_centered, 75 | sdl.windowpos_centered, width * 2, height * 2, flags) 76 | 77 | if window == sdl.null { 78 | eprintln('sdl.create_window() error: ${unsafe { cstring_to_vstring(sdl.get_error()) }}') 79 | return 80 | } 81 | 82 | r_flags := u32(sdl.RendererFlags.accelerated) 83 | renderer := sdl.create_renderer(window, -1, r_flags) 84 | 85 | if renderer == sdl.null { 86 | eprintln('sdl.create_renderer() error: ${unsafe { cstring_to_vstring(sdl.get_error()) }}') 87 | return 88 | } 89 | 90 | mut tex := sdl.create_texture(renderer, sdl.Format.argb8888, sdl.TextureAccess.streaming, 91 | width, height) 92 | 93 | if tex == sdl.null { 94 | eprintln('sdl.create_texture() error: ${unsafe { cstring_to_vstring(sdl.get_error()) }}') 95 | return 96 | } 97 | 98 | defer { 99 | sdl.destroy_texture(tex) 100 | sdl.destroy_renderer(renderer) 101 | sdl.destroy_window(window) 102 | } 103 | 104 | profile := img.load(os.args[1].str) 105 | if profile == sdl.null { 106 | eprintln('Error trying to load profile .png file: ${unsafe { cstring_to_vstring(sdl.get_error()) }}') 107 | return 108 | } 109 | 110 | // Check size compatibility. 111 | if profile.w != width || profile.h != height { 112 | eprintln('Error, "${os.args[1]}" profile image must match lbm lattice size : ${profile.w}x${profile.h}') 113 | return 114 | } 115 | 116 | // Check profile is 1 byte / pixel. 117 | if (profile.pitch / width) != 1 { 118 | eprintln('Error profile file must be 1 byte per pixel') 119 | return 120 | } 121 | 122 | // Build a colormap to be used 123 | cm := Colormap.dual(low_color, middle_color, high_color, 384) 124 | 125 | // Now create Lattices, with respect to loaded profile. 126 | mut src := Lattice.new(width, height, profile.pixels) 127 | 128 | src.add_flow(1.0, Vi.east) 129 | src.randomize(0.2) 130 | src.normalize() 131 | 132 | mut dst := Lattice.new(width, height, profile.pixels) 133 | 134 | // Allocate pixel buffer to draw in. 135 | mut pixel_buffer := []u32{len: width * height} // Dyn array heap allocated. 136 | 137 | mut should_close := false 138 | mut frame := 0 139 | mut render_method := vorticity 140 | 141 | println('Showing vorticiy. Press "v" to show different parameters.') 142 | 143 | for { 144 | evt := sdl.Event{} 145 | for 0 < sdl.poll_event(&evt) { 146 | match evt.@type { 147 | .quit { 148 | should_close = true 149 | } 150 | .keydown { 151 | key := unsafe { sdl.KeyCode(evt.key.keysym.sym) } 152 | if key == sdl.KeyCode.escape { 153 | should_close = true 154 | break 155 | } 156 | // Show next view 157 | if key == sdl.KeyCode.v { 158 | mut i := renderers.index(render_method) 159 | i++ 160 | if i >= renderers.len { 161 | i = 0 162 | } 163 | render_method = renderers[i] 164 | println('Rendering : ${renderers_names[i]}') 165 | } 166 | } 167 | else {} 168 | } 169 | } 170 | if should_close { 171 | break 172 | } 173 | 174 | mut stop_watch := time.new_stopwatch() 175 | src.move(mut dst) 176 | dst.collide() 177 | render_method(dst, cm, mut pixel_buffer) // render_method can point different method ! 178 | draw_colormap(cm, mut pixel_buffer) 179 | 180 | // swap src and dst buffers. 181 | tmp := src 182 | src = dst 183 | dst = tmp 184 | 185 | blit_pixels(tex, pixel_buffer) 186 | frame++ 187 | stop_watch.stop() 188 | // println('Frame ${frame}, loop : ${stop_watch.elapsed().milliseconds()} milliseconds. ') 189 | 190 | sdl.render_clear(renderer) 191 | sdl.render_copy(renderer, tex, sdl.null, sdl.null) 192 | sdl.render_present(renderer) 193 | // sdl.delay(10) 194 | } 195 | } 196 | 197 | // No bound checking here 198 | // blit_pixels from buffer to texture. 199 | @[direct_array_access] 200 | fn blit_pixels(t &sdl.Texture, data []u32) { 201 | mut pixels := unsafe { voidptr(nil) } 202 | mut pitch := int(0) 203 | 204 | success := sdl.lock_texture(t, sdl.null, &pixels, &pitch) 205 | if success < 0 { 206 | panic('sdl.lock_texture error: ${sdl.get_error()}') 207 | } 208 | unsafe { vmemcpy(pixels, data.data, len_in_bytes) } 209 | sdl.unlock_texture(t) 210 | } 211 | 212 | fn draw_colormap(cm []u32, mut data []u32) { 213 | data[0] = 0xFF000000 214 | data[width] = 0xFF000000 215 | data[2 * width] = 0xFF000000 216 | for i in 0 .. cm.len { 217 | data[i + 1] = 0xFF000000 218 | data[i + width + 1] = cm[i] 219 | data[i + 1 + 2 * width] = 0xFF000000 220 | } 221 | data[cm.len] = 0xFF000000 222 | data[width + cm.len] = 0xFF000000 223 | data[2 * width + cm.len] = 0xFF000000 224 | } 225 | 226 | // densities is a Renderer type function 227 | fn densities(l Lattice, cm []u32, mut output []u32) { 228 | mut ind := 0 229 | 230 | min_rho := l.min_rho() 231 | max_rho := l.max_rho() 232 | linear := (max_rho - min_rho) / (cm.len - 1) 233 | 234 | for c in l.m { 235 | if c.obstacle == true { 236 | output[ind] = obstacle_color 237 | ind++ 238 | continue 239 | } 240 | 241 | rho := int((c.rho() - min_rho) / linear) 242 | output[ind] = cm[rho] 243 | ind++ 244 | } 245 | } 246 | 247 | // h_speed is a Renderer type function 248 | fn h_speed(l Lattice, cm []u32, mut output []u32) { 249 | mut ind := 0 250 | 251 | min_ux := l.min_ux() 252 | max_ux := l.max_ux() 253 | linear := (max_ux - min_ux) / (cm.len - 1) 254 | 255 | for c in l.m { 256 | if c.obstacle == true { 257 | output[ind] = obstacle_color 258 | ind++ 259 | continue 260 | } 261 | 262 | rho := int((c.ux() - min_ux) / linear) 263 | output[ind] = cm[rho] 264 | ind++ 265 | } 266 | } 267 | 268 | // h_speed is a Renderer type function 269 | fn v_speed(l Lattice, cm []u32, mut output []u32) { 270 | mut ind := 0 271 | 272 | min_uy := l.min_uy() 273 | max_uy := l.max_uy() 274 | linear := (max_uy - min_uy) / (cm.len - 1) 275 | 276 | for c in l.m { 277 | if c.obstacle == true { 278 | output[ind] = obstacle_color 279 | ind++ 280 | continue 281 | } 282 | 283 | rho := int((c.uy() - min_uy) / linear) 284 | output[ind] = cm[rho] 285 | ind++ 286 | } 287 | } 288 | 289 | // vorticity is a Renderer type function 290 | fn vorticity(l Lattice, cm []u32, mut output []u32) { 291 | mut min := 0.0 292 | mut max := 0.0 293 | cm2 := u32(cm.len / 2) 294 | mut vorticity_table := []f64{len: l.w * l.h} 295 | 296 | for y in 0 .. l.h { 297 | for x in 0 .. l.w { 298 | out := (y * l.w) + x 299 | if l.m[out].obstacle { 300 | vorticity_table[out] = -1000000.0 301 | } else { 302 | v := l.vorticity(x, y) 303 | vorticity_table[out] = v 304 | if min > v { 305 | min = v 306 | } 307 | if max < v { 308 | max = v 309 | } 310 | } 311 | } 312 | } 313 | 314 | linear := (max - min) / f64(cm.len - 1) 315 | 316 | for ind, v in vorticity_table { 317 | if v < -100.0 { 318 | output[ind] = obstacle_color 319 | } else { 320 | mut id := cm2 + u32(v / linear) 321 | 322 | if id < 0 { 323 | id = 0 324 | } else if id >= cm.len { 325 | id = u32(cm.len - 1) 326 | } 327 | output[ind] = cm[id] 328 | } 329 | } 330 | } 331 | -------------------------------------------------------------------------------- /image/image.c.v: -------------------------------------------------------------------------------- 1 | // Copyright(C) 2021 Lars Pontoppidan. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | module image 5 | 6 | // 7 | // SDL_image.h 8 | // 9 | import sdl 10 | 11 | pub const major_version = C.SDL_IMAGE_MAJOR_VERSION // 2 12 | 13 | pub const minor_version = C.SDL_IMAGE_MINOR_VERSION // 0 14 | 15 | pub const patchlevel = C.SDL_IMAGE_PATCHLEVEL // 5 16 | 17 | fn C.SDL_IMAGE_VERSION(v &sdl.Version) 18 | 19 | // image_version macro can be used to fill a version structure with the compile-time 20 | // version of the SDL_image library. 21 | pub fn image_version(v &sdl.Version) { 22 | C.SDL_IMAGE_VERSION(v) 23 | } 24 | 25 | // This is the version number macro for the current SDL_image version. 26 | pub fn C.SDL_IMAGE_COMPILEDVERSION() int 27 | 28 | // compiledversion is the version number macro for the current SDL_image version. 29 | pub fn compiledversion() int { 30 | return C.SDL_VERSIONNUM(major_version, minor_version, patchlevel) 31 | } 32 | 33 | // This macro will evaluate to true if compiled with SDL_image at least X.Y.Z. 34 | pub fn C.SDL_IMAGE_VERSION_ATLEAST(x int, y int, z int) bool 35 | 36 | // extern DECLSPEC const SDL_version * SDLCALL IMG_Linked_Version(void) 37 | fn C.IMG_Linked_Version() &C.SDL_version 38 | pub fn linked_version() &sdl.Version { 39 | return C.IMG_Linked_Version() 40 | } 41 | 42 | // InitFlags isC.IMG_InitFlags 43 | pub enum InitFlags { 44 | jpg = C.IMG_INIT_JPG // 0x00000001 45 | png = C.IMG_INIT_PNG // 0x00000002 46 | tif = C.IMG_INIT_TIF // 0x00000004 47 | webp = C.IMG_INIT_WEBP // 0x00000008 48 | } 49 | 50 | fn C.IMG_Init(flags int) int 51 | 52 | // init loads dynamic libraries and prepares them for use. Flags should be 53 | // one or more flags from IMG_InitFlags OR'd together. 54 | // It returns the flags successfully initialized, or 0 on failure. 55 | pub fn init(flags int) int { 56 | return C.IMG_Init(flags) 57 | } 58 | 59 | fn C.IMG_Quit() 60 | 61 | // quit unloads libraries loaded with IMG_Init 62 | pub fn quit() { 63 | C.IMG_Quit() 64 | } 65 | 66 | fn C.IMG_LoadTyped_RW(src &C.SDL_RWops, freesrc int, const_type &char) &C.SDL_Surface 67 | 68 | // load_typed_rw loads an image from an SDL data source. 69 | // The 'type' may be one of: "BMP", "GIF", "PNG", etc. 70 | // 71 | // If the image format supports a transparent pixel, SDL will set the 72 | // colorkey for the surface. You can enable RLE acceleration on the 73 | // surface afterwards by calling: 74 | // SDL_SetColorKey(image, SDL_RLEACCEL, image->format->colorkey); 75 | pub fn load_typed_rw(src &sdl.RWops, freesrc int, const_type &char) &sdl.Surface { 76 | return C.IMG_LoadTyped_RW(src, freesrc, const_type) 77 | } 78 | 79 | // Convenience functions 80 | fn C.IMG_Load(file &char) &C.SDL_Surface 81 | pub fn load(file &char) &sdl.Surface { 82 | return C.IMG_Load(file) 83 | } 84 | 85 | fn C.IMG_Load_RW(src &C.SDL_RWops, freesrc int) &C.SDL_Surface 86 | pub fn load_rw(src &sdl.RWops, freesrc int) &sdl.Surface { 87 | return C.IMG_Load_RW(src, freesrc) 88 | } 89 | 90 | fn C.IMG_LoadTexture(renderer &C.SDL_Renderer, const_file &char) &C.SDL_Texture 91 | 92 | // load_texture loads an image directly into a render texture. 93 | pub fn load_texture(renderer &sdl.Renderer, const_file &char) &sdl.Texture { 94 | return C.IMG_LoadTexture(renderer, const_file) 95 | } 96 | 97 | fn C.IMG_LoadTexture_RW(renderer &C.SDL_Renderer, src &C.SDL_RWops, freesrc int) &C.SDL_Texture 98 | pub fn load_texture_rw(renderer &sdl.Renderer, src &sdl.RWops, freesrc int) &sdl.Texture { 99 | return C.IMG_LoadTexture_RW(renderer, src, freesrc) 100 | } 101 | 102 | fn C.IMG_LoadTextureTyped_RW(renderer &C.SDL_Renderer, src &C.SDL_RWops, freesrc int, const_type &char) &C.SDL_Texture 103 | pub fn load_texture_typed_rw(renderer &sdl.Renderer, src &sdl.RWops, freesrc int, const_type &char) &sdl.Texture { 104 | return C.IMG_LoadTextureTyped_RW(renderer, src, freesrc, const_type) 105 | } 106 | 107 | // Functions to detect a file type, given a seekable source 108 | fn C.IMG_isICO(src &C.SDL_RWops) int 109 | pub fn is_ico(src &sdl.RWops) int { 110 | return C.IMG_isICO(src) 111 | } 112 | 113 | fn C.IMG_isCUR(src &C.SDL_RWops) int 114 | pub fn is_cur(src &sdl.RWops) int { 115 | return C.IMG_isCUR(src) 116 | } 117 | 118 | fn C.IMG_isBMP(src &C.SDL_RWops) int 119 | pub fn is_bmp(src &sdl.RWops) int { 120 | return C.IMG_isBMP(src) 121 | } 122 | 123 | fn C.IMG_isGIF(src &C.SDL_RWops) int 124 | pub fn is_gif(src &sdl.RWops) int { 125 | return C.IMG_isGIF(src) 126 | } 127 | 128 | fn C.IMG_isJPG(src &C.SDL_RWops) int 129 | pub fn is_jpg(src &sdl.RWops) int { 130 | return C.IMG_isJPG(src) 131 | } 132 | 133 | fn C.IMG_isLBM(src &C.SDL_RWops) int 134 | pub fn is_lbm(src &sdl.RWops) int { 135 | return C.IMG_isLBM(src) 136 | } 137 | 138 | fn C.IMG_isPCX(src &C.SDL_RWops) int 139 | pub fn is_pcx(src &sdl.RWops) int { 140 | return C.IMG_isPCX(src) 141 | } 142 | 143 | fn C.IMG_isPNG(src &C.SDL_RWops) int 144 | pub fn is_png(src &sdl.RWops) int { 145 | return C.IMG_isPNG(src) 146 | } 147 | 148 | fn C.IMG_isPNM(src &C.SDL_RWops) int 149 | pub fn is_pnm(src &sdl.RWops) int { 150 | return C.IMG_isPNM(src) 151 | } 152 | 153 | fn C.IMG_isSVG(src &C.SDL_RWops) int 154 | pub fn is_svg(src &sdl.RWops) int { 155 | return C.IMG_isSVG(src) 156 | } 157 | 158 | fn C.IMG_isTIF(src &C.SDL_RWops) int 159 | pub fn is_tif(src &sdl.RWops) int { 160 | return C.IMG_isTIF(src) 161 | } 162 | 163 | fn C.IMG_isXCF(src &C.SDL_RWops) int 164 | pub fn is_xcf(src &sdl.RWops) int { 165 | return C.IMG_isXCF(src) 166 | } 167 | 168 | fn C.IMG_isXPM(src &C.SDL_RWops) int 169 | pub fn is_xpm(src &sdl.RWops) int { 170 | return C.IMG_isXPM(src) 171 | } 172 | 173 | fn C.IMG_isXV(src &C.SDL_RWops) int 174 | pub fn is_xv(src &sdl.RWops) int { 175 | return C.IMG_isXV(src) 176 | } 177 | 178 | fn C.IMG_isWEBP(src &C.SDL_RWops) int 179 | pub fn is_webp(src &sdl.RWops) int { 180 | return C.IMG_isWEBP(src) 181 | } 182 | 183 | // Individual loading functions 184 | fn C.IMG_LoadICO_RW(src &C.SDL_RWops) &C.SDL_Surface 185 | pub fn load_ico_rw(src &sdl.RWops) &sdl.Surface { 186 | return C.IMG_LoadICO_RW(src) 187 | } 188 | 189 | fn C.IMG_LoadCUR_RW(src &C.SDL_RWops) &C.SDL_Surface 190 | pub fn load_cur_rw(src &sdl.RWops) &sdl.Surface { 191 | return C.IMG_LoadCUR_RW(src) 192 | } 193 | 194 | fn C.IMG_LoadBMP_RW(src &C.SDL_RWops) &C.SDL_Surface 195 | pub fn load_bmp_rw(src &sdl.RWops) &sdl.Surface { 196 | return C.IMG_LoadBMP_RW(src) 197 | } 198 | 199 | fn C.IMG_LoadGIF_RW(src &C.SDL_RWops) &C.SDL_Surface 200 | pub fn load_gif_rw(src &sdl.RWops) &sdl.Surface { 201 | return C.IMG_LoadGIF_RW(src) 202 | } 203 | 204 | fn C.IMG_LoadJPG_RW(src &C.SDL_RWops) &C.SDL_Surface 205 | pub fn load_jpg_rw(src &sdl.RWops) &sdl.Surface { 206 | return C.IMG_LoadJPG_RW(src) 207 | } 208 | 209 | fn C.IMG_LoadLBM_RW(src &C.SDL_RWops) &C.SDL_Surface 210 | pub fn load_lbm_rw(src &sdl.RWops) &sdl.Surface { 211 | return C.IMG_LoadLBM_RW(src) 212 | } 213 | 214 | fn C.IMG_LoadPCX_RW(src &C.SDL_RWops) &C.SDL_Surface 215 | pub fn load_pcx_rw(src &sdl.RWops) &sdl.Surface { 216 | return C.IMG_LoadPCX_RW(src) 217 | } 218 | 219 | fn C.IMG_LoadPNG_RW(src &C.SDL_RWops) &C.SDL_Surface 220 | pub fn load_png_rw(src &sdl.RWops) &sdl.Surface { 221 | return C.IMG_LoadPNG_RW(src) 222 | } 223 | 224 | fn C.IMG_LoadPNM_RW(src &C.SDL_RWops) &C.SDL_Surface 225 | pub fn load_pnm_rw(src &sdl.RWops) &sdl.Surface { 226 | return C.IMG_LoadPNM_RW(src) 227 | } 228 | 229 | fn C.IMG_LoadSVG_RW(src &C.SDL_RWops) &C.SDL_Surface 230 | pub fn load_svg_rw(src &sdl.RWops) &sdl.Surface { 231 | return C.IMG_LoadSVG_RW(src) 232 | } 233 | 234 | fn C.IMG_LoadTGA_RW(src &C.SDL_RWops) &C.SDL_Surface 235 | pub fn load_tga_rw(src &sdl.RWops) &sdl.Surface { 236 | return C.IMG_LoadTGA_RW(src) 237 | } 238 | 239 | fn C.IMG_LoadTIF_RW(src &C.SDL_RWops) &C.SDL_Surface 240 | pub fn load_tif_rw(src &sdl.RWops) &sdl.Surface { 241 | return C.IMG_LoadTIF_RW(src) 242 | } 243 | 244 | fn C.IMG_LoadXCF_RW(src &C.SDL_RWops) &C.SDL_Surface 245 | pub fn load_xcf_rw(src &sdl.RWops) &sdl.Surface { 246 | return C.IMG_LoadXCF_RW(src) 247 | } 248 | 249 | fn C.IMG_LoadXPM_RW(src &C.SDL_RWops) &C.SDL_Surface 250 | pub fn load_xpm_rw(src &sdl.RWops) &sdl.Surface { 251 | return C.IMG_LoadXPM_RW(src) 252 | } 253 | 254 | fn C.IMG_LoadXV_RW(src &C.SDL_RWops) &C.SDL_Surface 255 | pub fn load_xv_rw(src &sdl.RWops) &sdl.Surface { 256 | return C.IMG_LoadXV_RW(src) 257 | } 258 | 259 | fn C.IMG_LoadWEBP_RW(src &C.SDL_RWops) &C.SDL_Surface 260 | pub fn load_webp_rw(src &sdl.RWops) &sdl.Surface { 261 | return C.IMG_LoadWEBP_RW(src) 262 | } 263 | 264 | fn C.IMG_ReadXPMFromArray(xpm &&char) &C.SDL_Surface 265 | pub fn read_xpm_from_array(xpm &&char) &sdl.Surface { 266 | return C.IMG_ReadXPMFromArray(xpm) 267 | } 268 | 269 | // Individual saving functions 270 | fn C.IMG_SavePNG(surface &C.SDL_Surface, const_file &char) int 271 | pub fn save_png(surface &sdl.Surface, const_file &char) int { 272 | return C.IMG_SavePNG(surface, const_file) 273 | } 274 | 275 | fn C.IMG_SavePNG_RW(surface &C.SDL_Surface, dst &C.SDL_RWops, freedst int) int 276 | pub fn save_png_rw(surface &sdl.Surface, dst &sdl.RWops, freedst int) int { 277 | return C.IMG_SavePNG_RW(surface, dst, freedst) 278 | } 279 | 280 | fn C.IMG_SaveJPG(surface &C.SDL_Surface, const_file &char, quality int) int 281 | pub fn save_jpg(surface &sdl.Surface, const_file &char, quality int) int { 282 | return C.IMG_SaveJPG(surface, const_file, quality) 283 | } 284 | 285 | fn C.IMG_SaveJPG_RW(surface &C.SDL_Surface, dst &C.SDL_RWops, freedst int, quality int) int 286 | pub fn save_jpg_rw(surface &sdl.Surface, dst &sdl.RWops, freedst int, quality int) int { 287 | return C.IMG_SaveJPG_RW(surface, dst, freedst, quality) 288 | } 289 | --------------------------------------------------------------------------------