From 608acbb03f976b0fbf23877d8b4b6ad7529e1d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Tue, 18 Mar 2014 12:04:46 +0100 Subject: Initial commit --- .gitignore | 4 + LICENSE | 13 +++ Makefile | 21 +++++ README.md | 13 +++ c_src/Makefile | 28 ++++++ c_src/esdl2.c | 36 ++++++++ c_src/esdl2.h | 137 ++++++++++++++++++++++++++++++ c_src/nif_helpers.h | 109 ++++++++++++++++++++++++ c_src/sdl.c | 93 ++++++++++++++++++++ c_src/sdl_events.c | 179 +++++++++++++++++++++++++++++++++++++++ c_src/sdl_renderer.c | 154 +++++++++++++++++++++++++++++++++ c_src/sdl_surface.c | 41 +++++++++ c_src/sdl_texture.c | 42 +++++++++ c_src/sdl_window.c | 65 ++++++++++++++ examples/hello_sdl/erlang.png | Bin 0 -> 12661 bytes examples/hello_sdl/hello_sdl.erl | 37 ++++++++ examples/hello_sdl/start.sh | 2 + src/esdl2.erl | 111 ++++++++++++++++++++++++ src/sdl.erl | 51 +++++++++++ src/sdl_events.erl | 20 +++++ src/sdl_renderer.erl | 40 +++++++++ src/sdl_surface.erl | 20 +++++ src/sdl_texture.erl | 25 ++++++ src/sdl_window.erl | 20 +++++ 24 files changed, 1261 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 c_src/Makefile create mode 100644 c_src/esdl2.c create mode 100644 c_src/esdl2.h create mode 100644 c_src/nif_helpers.h create mode 100644 c_src/sdl.c create mode 100644 c_src/sdl_events.c create mode 100644 c_src/sdl_renderer.c create mode 100644 c_src/sdl_surface.c create mode 100644 c_src/sdl_texture.c create mode 100644 c_src/sdl_window.c create mode 100644 examples/hello_sdl/erlang.png create mode 100644 examples/hello_sdl/hello_sdl.erl create mode 100755 examples/hello_sdl/start.sh create mode 100644 src/esdl2.erl create mode 100644 src/sdl.erl create mode 100644 src/sdl_events.erl create mode 100644 src/sdl_renderer.erl create mode 100644 src/sdl_surface.erl create mode 100644 src/sdl_texture.erl create mode 100644 src/sdl_window.erl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..60ef3c4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +c_src/env.mk +ebin +examples/*/*.beam +priv diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..63b312f --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2014, Loïc Hoguin + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d47278b --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +# Copyright (c) 2014, Loïc Hoguin +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +all: + rm -rf ebin/ + mkdir -p ebin/ + erlc -o ebin/ src/*.erl + cd c_src && make + erlc -o examples/hello_sdl examples/hello_sdl/*.erl + cd examples/hello_sdl && ./start.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..c00ee73 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +ESDL2 +===== + +SDL2 Erlang NIF. + +Status +------ + +Week-end project. Work in progress. + +You need at least Erlang 17.0 or a release candidate of it +for this project to run. It uses maps for a portion of its +interface. diff --git a/c_src/Makefile b/c_src/Makefile new file mode 100644 index 0000000..85cb8ce --- /dev/null +++ b/c_src/Makefile @@ -0,0 +1,28 @@ +# Copyright (c) 2014, Loïc Hoguin +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +PRIV_DIR ?= ../priv + +all: env.mk + mkdir -p $(PRIV_DIR) + gcc *.c -fPIC -shared -o $(PRIV_DIR)/esdl2.so -I $(ERTS_INCLUDE_DIR) \ + `sdl2-config --cflags` `sdl2-config --static-libs` -lSDL2_image + +env.mk: + erl -noshell -noinput -eval "file:write_file(\"env.mk\", \ + io_lib:format(\"ERTS_INCLUDE_DIR ?= ~s/erts-~s/include/\", \ + [code:root_dir(), erlang:system_info(version)])), \ + init:stop()." + +-include env.mk diff --git a/c_src/esdl2.c b/c_src/esdl2.c new file mode 100644 index 0000000..460526e --- /dev/null +++ b/c_src/esdl2.c @@ -0,0 +1,36 @@ +// Copyright (c) 2014, Loïc Hoguin +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#include "esdl2.h" + +NIF_ATOMS(NIF_ATOM_DECL) +NIF_RESOURCES(NIF_RES_DECL) + +int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) +{ + NIF_ATOMS(NIF_ATOM_INIT) + NIF_RESOURCES(NIF_RES_INIT) + + return 0; +} + +void unload(ErlNifEnv* env, void* priv_data) +{ +} + +static ErlNifFunc nif_funcs[] = { + NIF_FUNCTIONS(NIF_FUNCTION_ARRAY) +}; + +ERL_NIF_INIT(esdl2, nif_funcs, load, NULL, NULL, unload) diff --git a/c_src/esdl2.h b/c_src/esdl2.h new file mode 100644 index 0000000..d3c57c4 --- /dev/null +++ b/c_src/esdl2.h @@ -0,0 +1,137 @@ +// Copyright (c) 2014, Loïc Hoguin +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#ifndef __ESDL2_H__ +#define __ESDL2_H__ + +#include "SDL.h" + +// List of atoms used by this NIF. + +#define NIF_ATOMS(A) \ + A(button) \ + A(caps) \ + A(close) \ + A(data) \ + A(enter) \ + A(error) \ + A(event) \ + A(exposed) \ + A(false) \ + A(focus_gained) \ + A(focus_lost) \ + A(h) \ + A(hidden) \ + A(key_down) \ + A(key_up) \ + A(leave) \ + A(left) \ + A(left_alt) \ + A(left_ctrl) \ + A(left_gui) \ + A(left_shift) \ + A(ok) \ + A(maximized) \ + A(middle) \ + A(minimized) \ + A(mod) \ + A(mode) \ + A(mouse_down) \ + A(mouse_motion) \ + A(mouse_up) \ + A(mouse_wheel) \ + A(moved) \ + A(num) \ + A(quit) \ + A(repeat) \ + A(resized) \ + A(restored) \ + A(right) \ + A(right_alt) \ + A(right_ctrl) \ + A(right_gui) \ + A(right_shift) \ + A(scancode) \ + A(shown) \ + A(size_changed) \ + A(state) \ + A(sym) \ + A(touch) \ + A(true) \ + A(timestamp) \ + A(type) \ + A(undefined) \ + A(w) \ + A(which) \ + A(window) \ + A(window_id) \ + A(x) \ + A(x1) \ + A(x2) \ + A(xrel) \ + A(y) \ + A(yrel) \ + +// List of resources used by this NIF. + +#define NIF_RES_TYPE(r) SDL_ ## r +#define NIF_RESOURCES(R) \ + R(Renderer) \ + R(Surface) \ + R(Texture) \ + R(Window) + +// List of functions defined in this NIF. + +#define NIF_FUNCTION_NAME(f) esdl2_ ## f +#define NIF_FUNCTIONS(F) \ + /* sdl */ \ + F(init, 1) \ + F(init_subsystem, 1) \ + F(quit, 0) \ + F(quit_subsystem, 1) \ + F(set_main_ready, 0) \ + F(was_init, 1) \ + /* sdl_events */ \ + F(poll_event, 0) \ + /* sdl_renderer */ \ + F(create_renderer, 3) \ + F(render_clear, 1) \ + F(render_copy, 4) \ + F(render_present, 1) \ + F(set_render_draw_color, 5) \ + /* sdl_surface */ \ + F(img_load, 1) \ + /* sdl_texture */ \ + F(create_texture_from_surface, 2) \ + /* sdl_window */ \ + F(create_window, 6) + +// Generated declarations for the NIF. + +#include "nif_helpers.h" + +NIF_ATOMS(NIF_ATOM_H_DECL) +NIF_RESOURCES(NIF_RES_H_DECL) +NIF_FUNCTIONS(NIF_FUNCTION_H_DECL) + +// -- + +#define sdl_error_tuple(env) \ + enif_make_tuple2(env, \ + atom_error, \ + enif_make_string(env, SDL_GetError(), ERL_NIF_LATIN1) \ + ); + +#endif diff --git a/c_src/nif_helpers.h b/c_src/nif_helpers.h new file mode 100644 index 0000000..06eb787 --- /dev/null +++ b/c_src/nif_helpers.h @@ -0,0 +1,109 @@ +// Copyright (c) 2014, Loïc Hoguin +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#ifndef __NIF_HELPERS_H__ +#define __NIF_HELPERS_H__ + +#include "erl_nif.h" + +#define TO_STRING(i) #i + +// Atoms. + +#define MAX_ATOM_LENGTH 255 + +#define NIF_ATOM_DECL(a) ERL_NIF_TERM atom_ ## a; +#define NIF_ATOM_H_DECL(a) extern ERL_NIF_TERM atom_ ## a; +#define NIF_ATOM_INIT(a) atom_ ## a = enif_make_atom(env, #a); + +// Functions. + +#ifndef NIF_FUNCTION_NAME +#define NIF_FUNCTION_NAME(n) n +#endif + +#define NIF_FUNCTION(f) \ + ERL_NIF_TERM NIF_FUNCTION_NAME(f)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +#define NIF_FUNCTION_ARRAY(f, a) {#f, a, NIF_FUNCTION_NAME(f)}, +#define NIF_FUNCTION_H_DECL(f, a) \ + ERL_NIF_TERM NIF_FUNCTION_NAME(f)(ErlNifEnv*, int, const ERL_NIF_TERM []); + +#define BADARG_IF(cond) if (cond) return enif_make_badarg(env) + +// Resources. + +#ifndef NIF_RES_TYPE +#define NIF_RES_TYPE(t) t +#endif + +#define NIF_RES_DECL(r) ErlNifResourceType* res_ ## r = NULL; +#define NIF_RES_H_DECL(r) \ + extern ErlNifResourceType* res_ ## r; \ + void dtor_ ## r(ErlNifEnv*, void*); \ + typedef struct { \ + NIF_RES_TYPE(r)* v; \ + } obj_ ## r; +#define NIF_RES_INIT(r) \ + res_ ## r = enif_open_resource_type(env, NULL, TO_STRING(NIF_RES_TYPE(r)), dtor_ ## r, ERL_NIF_RT_CREATE, NULL); \ + if (!res_ ## r) return -1; + +#define NIF_RES_GET(r, obj) (((obj_ ## r*)obj)->v) +#define NIF_RES_TO_TERM(r, val, term) { \ + obj_ ## r* res = enif_alloc_resource(res_ ## r, sizeof(obj_ ## r)); \ + res->v = val; \ + term = enif_make_resource(env, res); \ + enif_release_resource(res); \ +} + +// Function generators. + +#define NIF_ATOM_TO_FLAG(a, f) if (!strcmp(buf, #a)) *flags |= f; else +#define NIF_LIST_TO_FLAGS_FUNCTION(f, type, flags_list) \ + int f(ErlNifEnv* env, ERL_NIF_TERM list, type* flags) \ + { \ + int i; \ + char buf[MAX_ATOM_LENGTH]; \ + ERL_NIF_TERM head; \ + \ + if (!enif_is_list(env, list)) \ + return 0; \ + \ + while (enif_get_list_cell(env, list, &head, &list)) { \ + if (!enif_get_atom(env, head, buf, MAX_ATOM_LENGTH, ERL_NIF_LATIN1)) \ + return 0; \ + \ + flags_list(NIF_ATOM_TO_FLAG) /* else */ return 0; \ + } \ + \ + return 1; \ + } + +#define NIF_FLAG_CONS_LIST(a, f) if (flags & f) list = enif_make_list_cell(env, atom_ ## a, list); +#define NIF_FLAGS_TO_LIST_FUNCTION(f, type, flags_list) \ + ERL_NIF_TERM f(ErlNifEnv* env, type flags) \ + { \ + ERL_NIF_TERM list = enif_make_list(env, 0); \ + flags_list(NIF_FLAG_CONS_LIST); \ + return list; \ + } + +#define NIF_ENUM_TO_ATOM(a, e) if (id == e) return atom_ ## a; +#define NIF_ENUM_TO_ATOM_FUNCTION(f, type, enum_list) \ + ERL_NIF_TERM f(type id) \ + { \ + enum_list(NIF_ENUM_TO_ATOM) \ + return atom_undefined; \ + } + +#endif diff --git a/c_src/sdl.c b/c_src/sdl.c new file mode 100644 index 0000000..6a429f3 --- /dev/null +++ b/c_src/sdl.c @@ -0,0 +1,93 @@ +// Copyright (c) 2014, Loïc Hoguin +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#include "esdl2.h" + +#define INIT_FLAGS(F) \ + F(timer, SDL_INIT_TIMER) \ + F(audio, SDL_INIT_AUDIO) \ + F(video, SDL_INIT_VIDEO) \ + F(joystick, SDL_INIT_JOYSTICK) \ + F(haptic, SDL_INIT_HAPTIC) \ + F(game_controller, SDL_INIT_GAMECONTROLLER) \ + F(events, SDL_INIT_EVENTS) \ + F(everything, SDL_INIT_EVERYTHING) \ + F(no_parachute, SDL_INIT_NOPARACHUTE) + +NIF_LIST_TO_FLAGS_FUNCTION(list_to_init_flags, Uint32, INIT_FLAGS) + +NIF_FUNCTION(init) +{ + Uint32 flags = 0; + + BADARG_IF(!list_to_init_flags(env, argv[0], &flags)); + + if (SDL_Init(flags) == 0) + return atom_ok; + + return sdl_error_tuple(env); +} + +NIF_FUNCTION(init_subsystem) +{ + Uint32 flags = 0; + + BADARG_IF(!list_to_init_flags(env, argv[0], &flags)); + + if (SDL_InitSubSystem(flags) == 0) + return atom_ok; + + return sdl_error_tuple(env); +} + +NIF_FUNCTION(quit) +{ + SDL_Quit(); + + return atom_ok; +} + +NIF_FUNCTION(quit_subsystem) +{ + Uint32 flags = 0; + + BADARG_IF(!list_to_init_flags(env, argv[0], &flags)); + + SDL_QuitSubSystem(flags); + + return atom_ok; +} + +NIF_FUNCTION(set_main_ready) +{ + SDL_SetMainReady(); + + return atom_ok; +} + +// @todo Implement the case where we want to receive a list of everything init. +NIF_FUNCTION(was_init) +{ + unsigned int length; + Uint32 flags = 0; + + BADARG_IF(!enif_get_list_length(env, argv[0], &length)); + BADARG_IF(length == 0); + BADARG_IF(!list_to_init_flags(env, argv[0], &flags)); + + if (SDL_WasInit(flags)) + return atom_true; + + return atom_false; +} diff --git a/c_src/sdl_events.c b/c_src/sdl_events.c new file mode 100644 index 0000000..4593a09 --- /dev/null +++ b/c_src/sdl_events.c @@ -0,0 +1,179 @@ +// Copyright (c) 2014, Loïc Hoguin +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#include "esdl2.h" + +#define EVENT_TYPE_ENUM(E) \ + E(window, SDL_WINDOWEVENT) \ + E(key_down, SDL_KEYDOWN) \ + E(key_up, SDL_KEYUP) \ + E(mouse_motion, SDL_MOUSEMOTION) \ + E(mouse_down, SDL_MOUSEBUTTONDOWN) \ + E(mouse_up, SDL_MOUSEBUTTONUP) \ + E(mouse_wheel, SDL_MOUSEWHEEL) \ + E(quit, SDL_QUIT) + +NIF_ENUM_TO_ATOM_FUNCTION(event_type_to_atom, Uint32, EVENT_TYPE_ENUM) + +#define WINDOW_EVENT_ENUM(E) \ + E(shown, SDL_WINDOWEVENT_SHOWN) \ + E(hidden, SDL_WINDOWEVENT_HIDDEN) \ + E(exposed, SDL_WINDOWEVENT_EXPOSED) \ + E(moved, SDL_WINDOWEVENT_MOVED) \ + E(resized, SDL_WINDOWEVENT_RESIZED) \ + E(size_changed, SDL_WINDOWEVENT_SIZE_CHANGED) \ + E(minimized, SDL_WINDOWEVENT_MINIMIZED) \ + E(maximized, SDL_WINDOWEVENT_MAXIMIZED) \ + E(restored, SDL_WINDOWEVENT_RESTORED) \ + E(enter, SDL_WINDOWEVENT_ENTER) \ + E(leave, SDL_WINDOWEVENT_LEAVE) \ + E(focus_gained, SDL_WINDOWEVENT_FOCUS_GAINED) \ + E(focus_lost, SDL_WINDOWEVENT_FOCUS_LOST) \ + E(close, SDL_WINDOWEVENT_CLOSE) + +NIF_ENUM_TO_ATOM_FUNCTION(window_event_to_atom, Uint8, WINDOW_EVENT_ENUM) + +#define KEYMOD_FLAGS(F) \ + F(left_shift, KMOD_LSHIFT) \ + F(right_shift, KMOD_RSHIFT) \ + F(left_ctrl, KMOD_LCTRL) \ + F(right_ctrl, KMOD_RCTRL) \ + F(left_alt, KMOD_LALT) \ + F(right_alt, KMOD_RALT) \ + F(left_gui, KMOD_LGUI) \ + F(right_gui, KMOD_RGUI) \ + F(num, KMOD_NUM) \ + F(caps, KMOD_CAPS) \ + F(mode, KMOD_MODE) + +NIF_FLAGS_TO_LIST_FUNCTION(keymod_flags_to_list, Uint16, KEYMOD_FLAGS) + +#define BUTTON_ENUM(E) \ + E(left, SDL_BUTTON_LEFT) \ + E(middle, SDL_BUTTON_MIDDLE) \ + E(right, SDL_BUTTON_RIGHT) \ + E(x1, SDL_BUTTON_X1) \ + E(x2, SDL_BUTTON_X2) + +NIF_ENUM_TO_ATOM_FUNCTION(button_to_atom, Uint8, BUTTON_ENUM) + +NIF_FUNCTION(poll_event) +{ + SDL_Event event; + ERL_NIF_TERM map; + + if (SDL_PollEvent(&event) == 0) + return atom_false; + + map = enif_make_new_map(env); + + // All events have a type and a timestamp. + enif_make_map_put(env, map, atom_type, + event_type_to_atom(event.type), &map); + enif_make_map_put(env, map, atom_timestamp, + enif_make_uint(env, event.common.timestamp), &map); + + // Some events have additional information. + if (event.type == SDL_WINDOWEVENT) { + enif_make_map_put(env, map, atom_window_id, + enif_make_uint(env, event.window.windowID), &map); + enif_make_map_put(env, map, atom_event, + window_event_to_atom(event.window.event), &map); + enif_make_map_put(env, map, atom_data, + enif_make_tuple2(env, + enif_make_int(env, event.window.data1), + enif_make_int(env, event.window.data2)), + &map); + } else if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) { + enif_make_map_put(env, map, atom_window_id, + enif_make_uint(env, event.key.windowID), &map); + // We don't pass the state as this information is redundant with the type. + enif_make_map_put(env, map, atom_repeat, + event.key.repeat == 0 ? atom_false : atom_true, &map); + enif_make_map_put(env, map, atom_scancode, + enif_make_uint(env, event.key.keysym.scancode), &map); + enif_make_map_put(env, map, atom_sym, + enif_make_uint(env, event.key.keysym.sym), &map); + enif_make_map_put(env, map, atom_mod, + keymod_flags_to_list(env, event.key.keysym.mod), &map); + } else if (event.type == SDL_MOUSEMOTION) { + enif_make_map_put(env, map, atom_window_id, + enif_make_uint(env, event.motion.windowID), &map); + enif_make_map_put(env, map, atom_which, + (event.motion.which == SDL_TOUCH_MOUSEID) + ? atom_touch + : enif_make_uint(env, event.motion.which), + &map); + // @todo We may want the state value here as it's a bitmask. + // Question is how do we represent it to the Erlang code? + enif_make_map_put(env, map, atom_x, + enif_make_int(env, event.motion.x), &map); + enif_make_map_put(env, map, atom_y, + enif_make_int(env, event.motion.y), &map); + enif_make_map_put(env, map, atom_xrel, + enif_make_int(env, event.motion.xrel), &map); + enif_make_map_put(env, map, atom_yrel, + enif_make_int(env, event.motion.yrel), &map); + } else if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) { + enif_make_map_put(env, map, atom_window_id, + enif_make_uint(env, event.button.windowID), &map); + enif_make_map_put(env, map, atom_which, + (event.button.which == SDL_TOUCH_MOUSEID) + ? atom_touch + : enif_make_uint(env, event.button.which), + &map); + enif_make_map_put(env, map, atom_button, + (event.button.button <= SDL_BUTTON_X2) + ? button_to_atom(event.button.button) + : enif_make_uint(env, event.button.button), + &map); + // We don't pass the state as this information is redundant with the type. + // @todo SDL 2.0.2 clicks + enif_make_map_put(env, map, atom_x, + enif_make_int(env, event.button.x), &map); + enif_make_map_put(env, map, atom_y, + enif_make_int(env, event.button.y), &map); + } else if (event.type == SDL_MOUSEWHEEL) { + enif_make_map_put(env, map, atom_window_id, + enif_make_uint(env, event.wheel.windowID), &map); + enif_make_map_put(env, map, atom_which, + (event.wheel.which == SDL_TOUCH_MOUSEID) + ? atom_touch + : enif_make_uint(env, event.wheel.which), + &map); + enif_make_map_put(env, map, atom_x, + enif_make_int(env, event.wheel.x), &map); + enif_make_map_put(env, map, atom_y, + enif_make_int(env, event.wheel.y), &map); + } + + // @todo SDL_TextEditingEvent + // @todo SDL_TextInputEvent + // @todo SDL_JoyAxisEvent + // @todo SDL_JoyBallEvent + // @todo SDL_JoyHatEvent + // @todo SDL_JoyButtonEvent + // @todo SDL_JoyDeviceEvent + // @todo SDL_ControllerAxisEvent + // @todo SDL_ControllerButtonEvent + // @todo SDL_ControllerDeviceEvent + // @todo SDL_UserEvent + // @todo SDL_SysWMEvent + // @todo SDL_TouchFingerEvent + // @todo SDL_MultiGestureEvent + // @todo SDL_DollarGestureEvent + // @todo SDL_DropEvent + + return map; +} diff --git a/c_src/sdl_renderer.c b/c_src/sdl_renderer.c new file mode 100644 index 0000000..ae65436 --- /dev/null +++ b/c_src/sdl_renderer.c @@ -0,0 +1,154 @@ +// Copyright (c) 2014, Loïc Hoguin +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#include "esdl2.h" + +void dtor_Renderer(ErlNifEnv* env, void* obj) +{ + SDL_DestroyRenderer(NIF_RES_GET(Renderer, obj)); +} + +#define RENDERER_FLAGS(F) \ + F(software, SDL_RENDERER_SOFTWARE) \ + F(accelerated, SDL_RENDERER_ACCELERATED) \ + F(present_vsync, SDL_RENDERER_PRESENTVSYNC) \ + F(target_texture, SDL_RENDERER_TARGETTEXTURE) + +NIF_LIST_TO_FLAGS_FUNCTION(list_to_renderer_flags, Uint32, RENDERER_FLAGS) + +int map_to_rect(ErlNifEnv* env, ERL_NIF_TERM map, SDL_Rect* rect) +{ + ERL_NIF_TERM x, y, w, h; + + if (!enif_get_map_value(env, map, atom_x, &x)) + return 0; + if (!enif_get_map_value(env, map, atom_y, &y)) + return 0; + if (!enif_get_map_value(env, map, atom_w, &w)) + return 0; + if (!enif_get_map_value(env, map, atom_h, &h)) + return 0; + + if (!enif_get_int(env, x, &rect->x)) + return 0; + if (!enif_get_int(env, y, &rect->y)) + return 0; + if (!enif_get_int(env, w, &rect->w)) + return 0; + if (!enif_get_int(env, h, &rect->h)) + return 0; + + return 1; +} + +NIF_FUNCTION(create_renderer) +{ + void* window_res; + int index; + Uint32 flags = 0; + SDL_Renderer* renderer; + ERL_NIF_TERM term; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Window, &window_res)); + BADARG_IF(!enif_get_int(env, argv[1], &index)); + BADARG_IF(!list_to_renderer_flags(env, argv[2], &flags)); + + renderer = SDL_CreateRenderer(NIF_RES_GET(Window, window_res), index, flags); + if (!renderer) + return sdl_error_tuple(env); + + NIF_RES_TO_TERM(Renderer, renderer, term); + + return enif_make_tuple2(env, + atom_ok, + term + ); +} + +NIF_FUNCTION(render_clear) +{ + void* renderer_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Renderer, &renderer_res)); + + if (SDL_RenderClear(NIF_RES_GET(Renderer, renderer_res))) + return sdl_error_tuple(env); + + return atom_ok; +} + +NIF_FUNCTION(render_copy) +{ + void* renderer_res; + void* texture_res; + SDL_Rect src, *srcPtr, dst, *dstPtr; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Renderer, &renderer_res)); + BADARG_IF(!enif_get_resource(env, argv[1], res_Texture, &texture_res)); + + if (enif_is_identical(argv[2], atom_undefined)) + srcPtr = NULL; + else { + BADARG_IF(!enif_is_map(env, argv[2])); + + srcPtr = &src; + if (!map_to_rect(env, argv[2], srcPtr)) + return enif_make_badarg(env); + } + + if (enif_is_identical(argv[3], atom_undefined)) + dstPtr = NULL; + else { + BADARG_IF(!enif_is_map(env, argv[3])); + + dstPtr = &dst; + if (!map_to_rect(env, argv[3], dstPtr)) + return enif_make_badarg(env); + } + + if (SDL_RenderCopy(NIF_RES_GET(Renderer, renderer_res), NIF_RES_GET(Texture, texture_res), srcPtr, dstPtr)) + return sdl_error_tuple(env); + + return atom_ok; +} + +NIF_FUNCTION(render_present) +{ + void* renderer_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Renderer, &renderer_res)); + + SDL_RenderPresent(NIF_RES_GET(Renderer, renderer_res)); + + return atom_ok; +} + +NIF_FUNCTION(set_render_draw_color) +{ + void* renderer_res; + int r, g, b, a; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Renderer, &renderer_res)); + BADARG_IF(!enif_get_int(env, argv[1], &r)); + BADARG_IF(!enif_get_int(env, argv[2], &g)); + BADARG_IF(!enif_get_int(env, argv[3], &b)); + BADARG_IF(!enif_get_int(env, argv[4], &a)); + BADARG_IF(r < 0 || r > 255 || g < 0 || g > 255 + || b < 0 || b > 255 || a < 0 || a > 255); + + if (SDL_SetRenderDrawColor(NIF_RES_GET(Renderer, renderer_res), r, g, b ,a)) + return sdl_error_tuple(env); + + return atom_ok; +} diff --git a/c_src/sdl_surface.c b/c_src/sdl_surface.c new file mode 100644 index 0000000..6f43f3e --- /dev/null +++ b/c_src/sdl_surface.c @@ -0,0 +1,41 @@ +// Copyright (c) 2014, Loïc Hoguin +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#include "esdl2.h" +#include "SDL_image.h" + +void dtor_Surface(ErlNifEnv* env, void* obj) +{ + SDL_FreeSurface(NIF_RES_GET(Surface, obj)); +} + +NIF_FUNCTION(img_load) +{ + char filename[FILENAME_MAX]; + SDL_Surface* surface; + ERL_NIF_TERM term; + + BADARG_IF(!enif_get_string(env, argv[0], filename, FILENAME_MAX, ERL_NIF_LATIN1)); + + surface = IMG_Load(filename); + if (!surface) + return sdl_error_tuple(env); + + NIF_RES_TO_TERM(Surface, surface, term); + + return enif_make_tuple2(env, + atom_ok, + term + ); +} diff --git a/c_src/sdl_texture.c b/c_src/sdl_texture.c new file mode 100644 index 0000000..daf5b93 --- /dev/null +++ b/c_src/sdl_texture.c @@ -0,0 +1,42 @@ +// Copyright (c) 2014, Loïc Hoguin +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#include "esdl2.h" + +void dtor_Texture(ErlNifEnv* env, void* obj) +{ + SDL_DestroyTexture(NIF_RES_GET(Texture, obj)); +} + +NIF_FUNCTION(create_texture_from_surface) +{ + void* renderer_res; + void* surface_res; + SDL_Texture* texture; + ERL_NIF_TERM term; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Renderer, &renderer_res)); + BADARG_IF(!enif_get_resource(env, argv[1], res_Surface, &surface_res)); + + texture = SDL_CreateTextureFromSurface(NIF_RES_GET(Renderer, renderer_res), NIF_RES_GET(Surface, surface_res)); + if (!texture) + return sdl_error_tuple(env); + + NIF_RES_TO_TERM(Texture, texture, term); + + return enif_make_tuple2(env, + atom_ok, + term + ); +} diff --git a/c_src/sdl_window.c b/c_src/sdl_window.c new file mode 100644 index 0000000..0a130f3 --- /dev/null +++ b/c_src/sdl_window.c @@ -0,0 +1,65 @@ +// Copyright (c) 2014, Loïc Hoguin +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#include "esdl2.h" + +void dtor_Window(ErlNifEnv* env, void* obj) +{ + SDL_DestroyWindow(NIF_RES_GET(Window, obj)); +} + +#define WINDOW_FLAGS(F) \ + F(fullscreen, SDL_WINDOW_FULLSCREEN) \ + F(fullscreen_desktop, SDL_WINDOW_FULLSCREEN_DESKTOP) \ + F(opengl, SDL_WINDOW_OPENGL) \ + F(shown, SDL_WINDOW_SHOWN) \ + F(hidden, SDL_WINDOW_HIDDEN) \ + F(borderless, SDL_WINDOW_BORDERLESS) \ + F(resizable, SDL_WINDOW_RESIZABLE) \ + F(minimized, SDL_WINDOW_MINIMIZED) \ + F(maximized, SDL_WINDOW_MAXIMIZED) \ + F(input_grabbed, SDL_WINDOW_INPUT_GRABBED) \ + F(input_focus, SDL_WINDOW_INPUT_FOCUS) \ + F(mouse_focus, SDL_WINDOW_MOUSE_FOCUS) \ + F(foreign, SDL_WINDOW_FOREIGN) \ + F(allow_high_dpi, SDL_WINDOW_ALLOW_HIGHDPI) + +NIF_LIST_TO_FLAGS_FUNCTION(list_to_window_flags, Uint32, WINDOW_FLAGS) + +NIF_FUNCTION(create_window) +{ + char title[255]; + int x, y, w, h; + Uint32 flags = 0; + SDL_Window* window; + ERL_NIF_TERM term; + + BADARG_IF(!enif_get_string(env, argv[0], title, 255, ERL_NIF_LATIN1)); + BADARG_IF(!enif_get_int(env, argv[1], &x)); + BADARG_IF(!enif_get_int(env, argv[2], &y)); + BADARG_IF(!enif_get_int(env, argv[3], &w)); + BADARG_IF(!enif_get_int(env, argv[4], &h)); + BADARG_IF(!list_to_window_flags(env, argv[5], &flags)); + + window = SDL_CreateWindow(title, x, y, w, h, flags); + if (!window) + return sdl_error_tuple(env); + + NIF_RES_TO_TERM(Window, window, term); + + return enif_make_tuple2(env, + atom_ok, + term + ); +} diff --git a/examples/hello_sdl/erlang.png b/examples/hello_sdl/erlang.png new file mode 100644 index 0000000..e8cad3a Binary files /dev/null and b/examples/hello_sdl/erlang.png differ diff --git a/examples/hello_sdl/hello_sdl.erl b/examples/hello_sdl/hello_sdl.erl new file mode 100644 index 0000000..4e06baf --- /dev/null +++ b/examples/hello_sdl/hello_sdl.erl @@ -0,0 +1,37 @@ +%% This is an example. Feel free to copy and reuse as you wish. + +-module(hello_sdl). +-export([run/0]). + +run() -> + spawn_opt(fun init/0, [{scheduler, 0}]). + +init() -> + ok = sdl:start([video]), + ok = sdl:stop_on_exit(), + {ok, Window} = sdl_window:create("Hello SDL", 10, 10, 500, 500, []), + {ok, Renderer} = sdl_renderer:create(Window, -1, [accelerated, present_vsync]), + ok = sdl_renderer:set_draw_color(Renderer, 255, 255, 255, 255), + {ok, Texture} = sdl_texture:create_from_file(Renderer, "erlang.png"), + loop(#{window=>Window, renderer=>Renderer, texture=>Texture}). + +loop(State) -> + events_loop(), + render(State), + loop(State). + +events_loop() -> + case sdl_events:poll() of + false -> ok; + #{type:=quit} -> terminate(); + _ -> events_loop() + end. + +render(#{renderer:=Renderer, texture:=Texture}) -> + ok = sdl_renderer:clear(Renderer), + ok = sdl_renderer:copy(Renderer, Texture, undefined, #{x=>100, y=>100, w=>300, h=>300}), + ok = sdl_renderer:present(Renderer). + +terminate() -> + init:stop(), + exit(normal). diff --git a/examples/hello_sdl/start.sh b/examples/hello_sdl/start.sh new file mode 100755 index 0000000..3d44558 --- /dev/null +++ b/examples/hello_sdl/start.sh @@ -0,0 +1,2 @@ +#!/bin/sh +erl +stbt db -pa ../../ebin -eval "hello_sdl:run()." diff --git a/src/esdl2.erl b/src/esdl2.erl new file mode 100644 index 0000000..a786685 --- /dev/null +++ b/src/esdl2.erl @@ -0,0 +1,111 @@ +%% Copyright (c) 2014, Loïc Hoguin +%% +%% Permission to use, copy, modify, and/or distribute this software for any +%% purpose with or without fee is hereby granted, provided that the above +%% copyright notice and this permission notice appear in all copies. +%% +%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +-module(esdl2). + +%% sdl +-export([init/1]). +-export([init_subsystem/1]). +-export([quit/0]). +-export([quit_subsystem/1]). +-export([set_main_ready/0]). +-export([was_init/1]). + +%% sdl_events +-export([poll_event/0]). + +%% sdl_renderer +-export([create_renderer/3]). +-export([render_clear/1]). +-export([render_copy/4]). +-export([render_present/1]). +-export([set_render_draw_color/5]). + +%% sdl_surface +-export([img_load/1]). + +%% sdl_texture +-export([create_texture_from_surface/2]). + +%% sdl_window +-export([create_window/6]). + +%% @todo We probably want to accept an env variable or somthing for the location. +-on_load(on_load/0). +on_load() -> + PrivDir = case code:priv_dir(?MODULE) of + {error, _} -> + AppPath = filename:dirname(filename:dirname(code:which(?MODULE))), + filename:join(AppPath, "priv"); + Path -> + Path + end, + erlang:load_nif(filename:join(PrivDir, atom_to_list(?MODULE)), 0). + +%% sdl + +init(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +init_subsystem(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +quit() -> + erlang:nif_error({not_loaded, ?MODULE}). + +quit_subsystem(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +set_main_ready() -> + erlang:nif_error({not_loaded, ?MODULE}). + +was_init(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +%% sdl_events + +poll_event() -> + erlang:nif_error({not_loaded, ?MODULE}). + +%% sdl_renderer + +create_renderer(_, _, _) -> + erlang:nif_error({not_loaded, ?MODULE}). + +render_clear(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +render_copy(_, _, _, _) -> + erlang:nif_error({not_loaded, ?MODULE}). + +render_present(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +set_render_draw_color(_, _, _, _, _) -> + erlang:nif_error({not_loaded, ?MODULE}). + +%% sdl_surface + +img_load(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +%% sdl_texture + +create_texture_from_surface(_, _) -> + erlang:nif_error({not_loaded, ?MODULE}). + +%% sdl_window + +create_window(_, _, _, _, _, _) -> + erlang:nif_error({not_loaded, ?MODULE}). diff --git a/src/sdl.erl b/src/sdl.erl new file mode 100644 index 0000000..b7adae6 --- /dev/null +++ b/src/sdl.erl @@ -0,0 +1,51 @@ +%% Copyright (c) 2014, Loïc Hoguin +%% +%% Permission to use, copy, modify, and/or distribute this software for any +%% purpose with or without fee is hereby granted, provided that the above +%% copyright notice and this permission notice appear in all copies. +%% +%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +-module(sdl). + +-export([start/0]). +-export([start/1]). +-export([stop/0]). +-export([stop_on_exit/0]). +-export([start_subsystems/1]). +-export([stop_subsystems/1]). +-export([is_started/1]). + +start() -> + esdl2:init([]). + +start(Subsystems) -> + esdl2:init(Subsystems). + +stop() -> + esdl2:quit(). + +stop_on_exit() -> + Self = self(), + spawn_link(fun() -> + process_flag(trap_exit, true), + receive {'EXIT', Self, _} -> + stop() + end + end), + ok. + +start_subsystems(Subsystems) -> + esdl2:init_subsystem(Subsystems). + +stop_subsystems(Subsystems) -> + esdl2:quit_subsystem(Subsystems). + +is_started(Subsystem) -> + esdl2:was_init([Subsystem]). diff --git a/src/sdl_events.erl b/src/sdl_events.erl new file mode 100644 index 0000000..2cd6c3f --- /dev/null +++ b/src/sdl_events.erl @@ -0,0 +1,20 @@ +%% Copyright (c) 2014, Loïc Hoguin +%% +%% Permission to use, copy, modify, and/or distribute this software for any +%% purpose with or without fee is hereby granted, provided that the above +%% copyright notice and this permission notice appear in all copies. +%% +%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +-module(sdl_events). + +-export([poll/0]). + +poll() -> + esdl2:poll_event(). diff --git a/src/sdl_renderer.erl b/src/sdl_renderer.erl new file mode 100644 index 0000000..2fff74f --- /dev/null +++ b/src/sdl_renderer.erl @@ -0,0 +1,40 @@ +%% Copyright (c) 2014, Loïc Hoguin +%% +%% Permission to use, copy, modify, and/or distribute this software for any +%% purpose with or without fee is hereby granted, provided that the above +%% copyright notice and this permission notice appear in all copies. +%% +%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +-module(sdl_renderer). + +-export([create/3]). +-export([clear/1]). +-export([copy/2]). +-export([copy/4]). +-export([present/1]). +-export([set_draw_color/5]). + +create(Window, Index, Flags) -> + esdl2:create_renderer(Window, Index, Flags). + +clear(Renderer) -> + esdl2:render_clear(Renderer). + +copy(Renderer, Texture) -> + esdl2:render_copy(Renderer, Texture, undefined, undefined). + +copy(Renderer, Texture, SrcRect, DstRect) -> + esdl2:render_copy(Renderer, Texture, SrcRect, DstRect). + +present(Renderer) -> + esdl2:render_present(Renderer). + +set_draw_color(Renderer, R, G, B, A) -> + esdl2:set_render_draw_color(Renderer, R, G, B, A). diff --git a/src/sdl_surface.erl b/src/sdl_surface.erl new file mode 100644 index 0000000..f36407f --- /dev/null +++ b/src/sdl_surface.erl @@ -0,0 +1,20 @@ +%% Copyright (c) 2014, Loïc Hoguin +%% +%% Permission to use, copy, modify, and/or distribute this software for any +%% purpose with or without fee is hereby granted, provided that the above +%% copyright notice and this permission notice appear in all copies. +%% +%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +-module(sdl_surface). + +-export([load/1]). + +load(Filename) -> + esdl2:img_load(Filename). diff --git a/src/sdl_texture.erl b/src/sdl_texture.erl new file mode 100644 index 0000000..f181bc1 --- /dev/null +++ b/src/sdl_texture.erl @@ -0,0 +1,25 @@ +%% Copyright (c) 2014, Loïc Hoguin +%% +%% Permission to use, copy, modify, and/or distribute this software for any +%% purpose with or without fee is hereby granted, provided that the above +%% copyright notice and this permission notice appear in all copies. +%% +%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +-module(sdl_texture). + +-export([create_from_file/2]). +-export([create_from_surface/2]). + +create_from_file(Renderer, Filename) -> + {ok, Surface} = sdl_surface:load(Filename), + create_from_surface(Renderer, Surface). + +create_from_surface(Renderer, Surface) -> + esdl2:create_texture_from_surface(Renderer, Surface). diff --git a/src/sdl_window.erl b/src/sdl_window.erl new file mode 100644 index 0000000..649ad8a --- /dev/null +++ b/src/sdl_window.erl @@ -0,0 +1,20 @@ +%% Copyright (c) 2014, Loïc Hoguin +%% +%% Permission to use, copy, modify, and/or distribute this software for any +%% purpose with or without fee is hereby granted, provided that the above +%% copyright notice and this permission notice appear in all copies. +%% +%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +-module(sdl_window). + +-export([create/6]). + +create(Title, X, Y, W, H, Flags) -> + esdl2:create_window(Title, X, Y, W, H, Flags). -- cgit v1.2.3