aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2014-03-18 12:04:46 +0100
committerLoïc Hoguin <[email protected]>2014-03-18 12:16:53 +0100
commit608acbb03f976b0fbf23877d8b4b6ad7529e1d53 (patch)
treef6ba7f0b5a37d270bfc64e07d02ebb0992631d8e
downloadesdl2-608acbb03f976b0fbf23877d8b4b6ad7529e1d53.tar.gz
esdl2-608acbb03f976b0fbf23877d8b4b6ad7529e1d53.tar.bz2
esdl2-608acbb03f976b0fbf23877d8b4b6ad7529e1d53.zip
Initial commit
-rw-r--r--.gitignore4
-rw-r--r--LICENSE13
-rw-r--r--Makefile21
-rw-r--r--README.md13
-rw-r--r--c_src/Makefile28
-rw-r--r--c_src/esdl2.c36
-rw-r--r--c_src/esdl2.h137
-rw-r--r--c_src/nif_helpers.h109
-rw-r--r--c_src/sdl.c93
-rw-r--r--c_src/sdl_events.c179
-rw-r--r--c_src/sdl_renderer.c154
-rw-r--r--c_src/sdl_surface.c41
-rw-r--r--c_src/sdl_texture.c42
-rw-r--r--c_src/sdl_window.c65
-rw-r--r--examples/hello_sdl/erlang.pngbin0 -> 12661 bytes
-rw-r--r--examples/hello_sdl/hello_sdl.erl37
-rwxr-xr-xexamples/hello_sdl/start.sh2
-rw-r--r--src/esdl2.erl111
-rw-r--r--src/sdl.erl51
-rw-r--r--src/sdl_events.erl20
-rw-r--r--src/sdl_renderer.erl40
-rw-r--r--src/sdl_surface.erl20
-rw-r--r--src/sdl_texture.erl25
-rw-r--r--src/sdl_window.erl20
24 files changed, 1261 insertions, 0 deletions
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 <[email protected]>
+
+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 <[email protected]>
+#
+# 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 <[email protected]>
+#
+# 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 <[email protected]>
+//
+// 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 <[email protected]>
+//
+// 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 <[email protected]>
+//
+// 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 <[email protected]>
+//
+// 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 <[email protected]>
+//
+// 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 <[email protected]>
+//
+// 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 <[email protected]>
+//
+// 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 <[email protected]>
+//
+// 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 <[email protected]>
+//
+// 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
--- /dev/null
+++ b/examples/hello_sdl/erlang.png
Binary files 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 <[email protected]>
+%%
+%% 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 <[email protected]>
+%%
+%% 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 <[email protected]>
+%%
+%% 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 <[email protected]>
+%%
+%% 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 <[email protected]>
+%%
+%% 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 <[email protected]>
+%%
+%% 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 <[email protected]>
+%%
+%% 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).