diff options
Diffstat (limited to 'c_src')
-rw-r--r-- | c_src/esdl2.h | 16 | ||||
-rw-r--r-- | c_src/sdl_pixels.c | 31 | ||||
-rw-r--r-- | c_src/sdl_surface.c | 19 | ||||
-rw-r--r-- | c_src/sdl_ttf.c | 158 |
4 files changed, 224 insertions, 0 deletions
diff --git a/c_src/esdl2.h b/c_src/esdl2.h index e4f0356..cad60a7 100644 --- a/c_src/esdl2.h +++ b/c_src/esdl2.h @@ -16,10 +16,12 @@ #define __ESDL2_H__ #include "SDL.h" +#include "SDL_ttf.h" // List of atoms used by this NIF. #define NIF_ATOMS(A) \ + A(a) \ A(abgr1555) \ A(abgr32) \ A(abgr4444) \ @@ -43,6 +45,7 @@ A(audio) \ A(audio_device_added) \ A(audio_device_removed) \ + A(b) \ A(bgr24) \ A(bgr555) \ A(bgr565) \ @@ -105,6 +108,7 @@ A(format) \ A(fullscreen) \ A(fullscreen_desktop) \ + A(g) \ A(game_controller) \ A(get) \ A(h) \ @@ -179,6 +183,7 @@ A(present_vsync) \ A(pressed) \ A(quit) \ + A(r) \ A(refresh_rate) \ A(released) \ A(render_device_reset) \ @@ -263,9 +268,12 @@ // List of resources used by this NIF. +#define SDL_Font TTF_Font + #define NIF_RES_TYPE(r) SDL_ ## r #define NIF_RESOURCES(R) \ R(Cursor) \ + R(Font) \ R(GLContext) \ R(Renderer) \ R(Surface) \ @@ -405,6 +413,7 @@ /* sdl_stdinc */ \ F(get_num_allocations, 0) \ /* sdl_surface */ \ + F(get_surface_dimensions, 1) \ F(img_load, 1) \ /* sdl_texture */ \ F(create_texture_from_surface, 2) \ @@ -414,6 +423,12 @@ F(set_texture_alpha_mod, 2) \ F(set_texture_blend_mode, 2) \ F(set_texture_color_mod, 4) \ + /* sdl_ttf */ \ + F(ttf_init, 0) \ + F(ttf_open_font, 2) \ + F(ttf_quit, 0) \ + F(ttf_render_utf8_solid, 3) \ + F(ttf_was_init, 0) \ /* sdl_version */ \ F(get_version, 0) \ F(get_revision, 0) \ @@ -504,6 +519,7 @@ NIF_ENUM_TO_ATOM_FUNCTION_DECL(window_event_to_atom, Uint8) NIF_LIST_TO_FLAGS_FUNCTION_DECL(keymod_list_to_flags, Uint16) NIF_FLAGS_TO_LIST_FUNCTION_DECL(keymod_flags_to_list, Uint16) +int map_to_color(ErlNifEnv*, ERL_NIF_TERM, SDL_Color*); int map_to_point(ErlNifEnv*, ERL_NIF_TERM, SDL_Point*); ERL_NIF_TERM point_to_map(ErlNifEnv*, const SDL_Point*); int map_to_rect(ErlNifEnv*, ERL_NIF_TERM, SDL_Rect*); diff --git a/c_src/sdl_pixels.c b/c_src/sdl_pixels.c index aa22329..1bdec60 100644 --- a/c_src/sdl_pixels.c +++ b/c_src/sdl_pixels.c @@ -60,3 +60,34 @@ NIF_ENUM_TO_ATOM_FUNCTION(pixel_format_to_atom, Uint32, PIXEL_FORMAT_ENUM) NIF_ATOM_TO_ENUM_FUNCTION(atom_to_pixel_format, Uint32, PIXEL_FORMAT_ENUM) + +int map_to_color(ErlNifEnv* env, ERL_NIF_TERM map, SDL_Color* color) +{ + ERL_NIF_TERM r, g, b, a; + unsigned int ri, gi, bi, ai; + + if (!enif_get_map_value(env, map, atom_r, &r)) + return 0; + if (!enif_get_map_value(env, map, atom_g, &g)) + return 0; + if (!enif_get_map_value(env, map, atom_b, &b)) + return 0; + if (!enif_get_map_value(env, map, atom_a, &a)) + return 0; + + if (!enif_get_uint(env, r, &ri)) + return 0; + if (!enif_get_uint(env, g, &gi)) + return 0; + if (!enif_get_uint(env, b, &bi)) + return 0; + if (!enif_get_uint(env, a, &ai)) + return 0; + + color->r = ri; + color->g = gi; + color->b = bi; + color->a = ai; + + return 1; +} diff --git a/c_src/sdl_surface.c b/c_src/sdl_surface.c index 22f75ab..a915fec 100644 --- a/c_src/sdl_surface.c +++ b/c_src/sdl_surface.c @@ -20,7 +20,26 @@ void dtor_Surface(ErlNifEnv* env, void* obj) SDL_FreeSurface(NIF_RES_GET(Surface, obj)); } +// get_surface_dimensions + +NIF_FUNCTION(get_surface_dimensions) +{ + void* surface_res; + SDL_Surface* surface; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Surface, &surface_res)); + surface = NIF_RES_GET(Surface, surface_res); + + return enif_make_tuple2(env, + enif_make_int(env, surface->w), + enif_make_int(env, surface->h) + ); +} + // img_load +// @todo We should accept file:filename_all() and convert to binary +// before passing it to the NIF. Then we can support UTF-8 paths. +// @todo This function probably doesn't need to be a call. NIF_CALL_HANDLER(thread_img_load) { diff --git a/c_src/sdl_ttf.c b/c_src/sdl_ttf.c new file mode 100644 index 0000000..7deb729 --- /dev/null +++ b/c_src/sdl_ttf.c @@ -0,0 +1,158 @@ +// Copyright (c) 2018, 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" + +// @todo These operations should probably occur in the thread. +void dtor_Font(ErlNifEnv* env, void* obj) +{ + TTF_Font* font = NIF_RES_GET(Font, obj); + + TTF_CloseFont(font); +} + +// ttf_init + +NIF_CALL_HANDLER(thread_ttf_init) +{ + if (TTF_Init()) + return sdl_error_tuple(env); + + return atom_ok; +} + +NIF_FUNCTION(ttf_init) +{ + return nif_thread_call(env, thread_ttf_init, 0); +} + +// ttf_openfont + +NIF_CALL_HANDLER(thread_ttf_open_font) +{ + TTF_Font* font; + obj_Font* res; + ERL_NIF_TERM term; + + font = TTF_OpenFont(args[0], (long)args[1]); + + enif_free(args[0]); + + if (!font) + return sdl_error_tuple(env); + + NIF_RES_TO_PTR_AND_TERM(Font, font, res, term); + + return enif_make_tuple2(env, + atom_ok, + term + ); +} + +NIF_FUNCTION(ttf_open_font) +{ + ErlNifBinary bin; + char* filename; + int ptsize; + + BADARG_IF(!enif_get_int(env, argv[1], &ptsize)); + + // Getting the filename last to simplify the code due to memory allocation. + + BADARG_IF(!enif_inspect_binary(env, argv[0], &bin)); + + filename = enif_alloc(bin.size + 1); + memcpy(filename, bin.data, bin.size); + filename[bin.size] = '\0'; + + return nif_thread_call(env, thread_ttf_open_font, 2, + filename, ptsize); +} + +// ttf_quit + +NIF_CAST_HANDLER(thread_ttf_quit) +{ + TTF_Quit(); +} + +NIF_FUNCTION(ttf_quit) +{ + return nif_thread_cast(env, thread_ttf_quit, 0); +} + +// ttf_render_utf8_solid + +NIF_CALL_HANDLER(thread_ttf_render_utf8_solid) +{ + SDL_Surface* surface; + obj_Surface* res; + ERL_NIF_TERM term; + + surface = TTF_RenderUTF8_Solid(args[0], args[1], *(SDL_Color*)args[2]); + + enif_free(args[1]); + enif_free(args[2]); + + if (!surface) + return sdl_error_tuple(env); + + NIF_RES_TO_PTR_AND_TERM(Surface, surface, res, term); + + return enif_make_tuple2(env, + atom_ok, + term + ); +} + +NIF_FUNCTION(ttf_render_utf8_solid) +{ + void* font_res; + ErlNifBinary bin; + char* text; + SDL_Color* color; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + BADARG_IF(!enif_inspect_binary(env, argv[1], &bin)); + + text = enif_alloc(bin.size + 1); + memcpy(text, bin.data, bin.size); + text[bin.size] = '\0'; + + color = enif_alloc(sizeof(SDL_Color)); + if (!map_to_color(env, argv[2], color)) { + enif_free(text); + enif_free(color); + + return enif_make_badarg(env); + } + + return nif_thread_call(env, thread_ttf_render_utf8_solid, 3, + NIF_RES_GET(Font, font_res), text, color); +} + +// ttf_was_init + +NIF_CALL_HANDLER(thread_ttf_was_init) +{ + if (TTF_WasInit()) + return atom_true; + + return atom_false; +} + +NIF_FUNCTION(ttf_was_init) +{ + return nif_thread_call(env, thread_ttf_was_init, 0); +} |