From 898c2ada209f3ab4e19d4b072aeef484baae27da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Sun, 7 Jan 2018 10:45:17 +0100 Subject: Add a bunch of sdl_renderer functions --- c_src/esdl2.h | 68 +++++++++++++++++++--- c_src/sdl_keyboard.c | 2 - c_src/sdl_pixels.c | 61 ++++++++++++++++++++ c_src/sdl_renderer.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 277 insertions(+), 10 deletions(-) create mode 100644 c_src/sdl_pixels.c (limited to 'c_src') diff --git a/c_src/esdl2.h b/c_src/esdl2.h index a9cf3f4..a860b7f 100644 --- a/c_src/esdl2.h +++ b/c_src/esdl2.h @@ -20,6 +20,10 @@ // List of atoms used by this NIF. #define NIF_ATOMS(A) \ + A(abgr1555) \ + A(abgr32) \ + A(abgr4444) \ + A(abgr8888) \ A(accelerated) \ A(add) \ A(allow_high_dpi) \ @@ -29,10 +33,24 @@ A(app_terminating) \ A(app_will_enter_background) \ A(app_will_enter_foreground) \ + A(argb1555) \ + A(argb2101010) \ + A(argb32) \ + A(argb4444) \ + A(argb8888) \ A(arrow) \ A(audio) \ A(audio_device_added) \ A(audio_device_removed) \ + A(bgr24) \ + A(bgr555) \ + A(bgr565) \ + A(bgr888) \ + A(bgra32) \ + A(bgra4444) \ + A(bgra5551) \ + A(bgra8888) \ + A(bgrx8888) \ A(blend) \ A(borderless) \ A(button) \ @@ -73,6 +91,7 @@ A(finger_motion) \ A(finger_up) \ A(first) \ + A(flags) \ A(flipped) \ A(focus_gained) \ A(focus_lost) \ @@ -88,9 +107,15 @@ A(hit_test) \ A(horizontal) \ A(ibeam) \ + A(index1lsb) \ + A(index1msb) \ + A(index4lsb) \ + A(index4msb) \ + A(index8) \ A(input_focus) \ A(input_grabbed) \ A(invalid) \ + A(iyuv) \ A(joy_axis_motion) \ A(joy_ball_motion) \ A(joy_button_down) \ @@ -109,11 +134,8 @@ A(left_ctrl) \ A(left_gui) \ A(left_shift) \ - A(ok) \ - A(one_minus_dst_alpha) \ - A(one_minus_dst_color) \ - A(one_minus_src_alpha) \ - A(one_minus_src_color) \ + A(max_texture_height) \ + A(max_texture_width) \ A(maximized) \ A(maximum) \ A(middle) \ @@ -129,26 +151,45 @@ A(mouse_wheel) \ A(moved) \ A(multi_gesture) \ + A(name) \ A(no) \ A(no_battery) \ A(none) \ A(normal) \ A(num) \ + A(nv12) \ + A(nv21) \ + A(ok) \ A(on_battery) \ A(one) \ + A(one_minus_dst_alpha) \ + A(one_minus_dst_color) \ + A(one_minus_src_alpha) \ + A(one_minus_src_color) \ A(opengl) \ A(peek) \ A(present_vsync) \ A(pressed) \ A(quit) \ A(released) \ - A(render_targets_reset) \ A(render_device_reset) \ + A(render_targets_reset) \ A(repeat) \ A(resizable) \ A(resized) \ A(restored) \ A(rev_substract) \ + A(rgb24) \ + A(rgb332) \ + A(rgb444) \ + A(rgb555) \ + A(rgb565) \ + A(rgb888) \ + A(rgba32) \ + A(rgba4444) \ + A(rgba5551) \ + A(rgba8888) \ + A(rgbx8888) \ A(right) \ A(right_alt) \ A(right_ctrl) \ @@ -173,13 +214,15 @@ A(target_texture) \ A(text_editing) \ A(text_input) \ - A(touch) \ - A(true) \ + A(texture_formats) \ A(timer) \ A(timestamp) \ + A(touch) \ + A(true) \ A(type) \ A(undefined) \ A(unknown) \ + A(uyvy) \ A(vertical) \ A(video) \ A(w) \ @@ -195,6 +238,9 @@ A(xrel) \ A(y) \ A(yrel) \ + A(yuy2) \ + A(yv12) \ + A(yvyu) \ A(zero) \ A(_nif_thread_ret_) @@ -304,7 +350,10 @@ F(get_num_render_drivers, 0) \ F(get_render_draw_blend_mode, 1) \ F(get_render_draw_color, 1) \ + F(get_render_driver_info, 1) \ F(get_render_output_size, 1) \ + F(get_renderer, 1) \ + F(get_renderer_info, 1) \ F(render_clear, 1) \ F(render_copy, 4) \ F(render_copy_ex, 7) \ @@ -317,11 +366,13 @@ F(render_fill_rect, 5) \ F(render_fill_rects, 2) \ F(render_get_clip_rect, 1) \ + F(render_get_integer_scale, 1) \ F(render_get_logical_size, 1) \ F(render_get_scale, 1) \ F(render_get_viewport, 1) \ F(render_present, 1) \ F(render_set_clip_rect, 5) \ + F(render_set_integer_scale, 2) \ F(render_set_logical_size, 3) \ F(render_set_scale, 3) \ F(render_set_viewport, 5) \ @@ -386,6 +437,7 @@ NIF_ATOM_TO_ENUM_FUNCTION_DECL(atom_to_blend_mode, SDL_BlendMode) NIF_ENUM_TO_ATOM_FUNCTION_DECL(blend_mode_to_atom, SDL_BlendMode) NIF_ENUM_TO_ATOM_FUNCTION_DECL(button_to_atom, Uint8) NIF_ENUM_TO_ATOM_FUNCTION_DECL(mousewheel_direction_to_atom, Uint32) +NIF_ENUM_TO_ATOM_FUNCTION_DECL(pixel_format_to_atom, Uint32) NIF_ENUM_TO_ATOM_FUNCTION_DECL(window_event_to_atom, Uint8) NIF_LIST_TO_FLAGS_FUNCTION_DECL(keymod_list_to_flags, Uint16) diff --git a/c_src/sdl_keyboard.c b/c_src/sdl_keyboard.c index f33a69d..5c402d4 100644 --- a/c_src/sdl_keyboard.c +++ b/c_src/sdl_keyboard.c @@ -69,7 +69,6 @@ NIF_CALL_HANDLER(thread_get_key_name) name = SDL_GetKeyName((long)args[0]); enif_alloc_binary(strlen(name), &bin); - memcpy(bin.data, name, bin.size); return enif_make_binary(env, &bin); @@ -141,7 +140,6 @@ NIF_FUNCTION(get_scancode_name) name = SDL_GetScancodeName(scancode); enif_alloc_binary(strlen(name), &bin); - memcpy(bin.data, name, bin.size); return enif_make_binary(env, &bin); diff --git a/c_src/sdl_pixels.c b/c_src/sdl_pixels.c new file mode 100644 index 0000000..08c9a61 --- /dev/null +++ b/c_src/sdl_pixels.c @@ -0,0 +1,61 @@ +// Copyright (c) 2018, 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 PIXEL_FORMAT_ENUM(E) \ + E(unknown, SDL_PIXELFORMAT_UNKNOWN) \ + E(index1lsb, SDL_PIXELFORMAT_INDEX1LSB) \ + E(index1msb, SDL_PIXELFORMAT_INDEX1MSB) \ + E(index4lsb, SDL_PIXELFORMAT_INDEX4LSB) \ + E(index4msb, SDL_PIXELFORMAT_INDEX4MSB) \ + E(index8, SDL_PIXELFORMAT_INDEX8) \ + E(rgb332, SDL_PIXELFORMAT_RGB332) \ + E(rgb444, SDL_PIXELFORMAT_RGB444) \ + E(rgb555, SDL_PIXELFORMAT_RGB555) \ + E(bgr555, SDL_PIXELFORMAT_BGR555) \ + E(argb4444, SDL_PIXELFORMAT_ARGB4444) \ + E(rgba4444, SDL_PIXELFORMAT_RGBA4444) \ + E(abgr4444, SDL_PIXELFORMAT_ABGR4444) \ + E(bgra4444, SDL_PIXELFORMAT_BGRA4444) \ + E(argb1555, SDL_PIXELFORMAT_ARGB1555) \ + E(rgba5551, SDL_PIXELFORMAT_RGBA5551) \ + E(abgr1555, SDL_PIXELFORMAT_ABGR1555) \ + E(bgra5551, SDL_PIXELFORMAT_BGRA5551) \ + E(rgb565, SDL_PIXELFORMAT_RGB565) \ + E(bgr565, SDL_PIXELFORMAT_BGR565) \ + E(rgb24, SDL_PIXELFORMAT_RGB24) \ + E(bgr24, SDL_PIXELFORMAT_BGR24) \ + E(rgb888, SDL_PIXELFORMAT_RGB888) \ + E(rgbx8888, SDL_PIXELFORMAT_RGBX8888) \ + E(bgr888, SDL_PIXELFORMAT_BGR888) \ + E(bgrx8888, SDL_PIXELFORMAT_BGRX8888) \ + E(argb8888, SDL_PIXELFORMAT_ARGB8888) \ + E(rgba8888, SDL_PIXELFORMAT_RGBA8888) \ + E(abgr8888, SDL_PIXELFORMAT_ABGR8888) \ + E(bgra8888, SDL_PIXELFORMAT_BGRA8888) \ + E(argb2101010, SDL_PIXELFORMAT_ARGB2101010) \ + E(rgba32, SDL_PIXELFORMAT_RGBA32) \ + E(argb32, SDL_PIXELFORMAT_ARGB32) \ + E(bgra32, SDL_PIXELFORMAT_BGRA32) \ + E(abgr32, SDL_PIXELFORMAT_ABGR32) \ + E(yv12, SDL_PIXELFORMAT_YV12) \ + E(iyuv, SDL_PIXELFORMAT_IYUV) \ + E(yuy2, SDL_PIXELFORMAT_YUY2) \ + E(uyvy, SDL_PIXELFORMAT_UYVY) \ + E(yvyu, SDL_PIXELFORMAT_YVYU) \ + E(nv12, SDL_PIXELFORMAT_NV12) \ + E(nv21, SDL_PIXELFORMAT_NV21) + +NIF_ENUM_TO_ATOM_FUNCTION(pixel_format_to_atom, Uint32, PIXEL_FORMAT_ENUM) diff --git a/c_src/sdl_renderer.c b/c_src/sdl_renderer.c index 60bfe85..7954fd3 100644 --- a/c_src/sdl_renderer.c +++ b/c_src/sdl_renderer.c @@ -29,6 +29,7 @@ void dtor_Renderer(ErlNifEnv* env, void* obj) F(target_texture, SDL_RENDERER_TARGETTEXTURE) static NIF_LIST_TO_FLAGS_FUNCTION(list_to_renderer_flags, Uint32, RENDERER_FLAGS) +static NIF_FLAGS_TO_LIST_FUNCTION(renderer_flags_to_list, Uint32, RENDERER_FLAGS) #define FLIP_FLAGS(F) \ F(none, SDL_FLIP_NONE) \ @@ -37,6 +38,42 @@ static NIF_LIST_TO_FLAGS_FUNCTION(list_to_renderer_flags, Uint32, RENDERER_FLAGS static NIF_LIST_TO_FLAGS_FUNCTION(list_to_flip_flags, SDL_RendererFlip, FLIP_FLAGS) +static ERL_NIF_TERM renderer_info_to_map(ErlNifEnv* env, SDL_RendererInfo* info) +{ + ERL_NIF_TERM map, list; + ErlNifBinary bin; + int i; + + map = enif_make_new_map(env); + + enif_alloc_binary(strlen(info->name), &bin); + memcpy(bin.data, info->name, bin.size); + + enif_make_map_put(env, map, atom_name, + enif_make_binary(env, &bin), &map); + + enif_make_map_put(env, map, atom_flags, + renderer_flags_to_list(env, info->flags), &map); + + list = enif_make_list(env, 0); + + for (i = 0; i < info->num_texture_formats; i++) { + list = enif_make_list_cell(env, + pixel_format_to_atom(info->texture_formats[i]), + list); + } + + enif_make_map_put(env, map, atom_texture_formats, list, &map); + + enif_make_map_put(env, map, atom_max_texture_width, + enif_make_int(env, info->max_texture_width), &map); + + enif_make_map_put(env, map, atom_max_texture_height, + enif_make_int(env, info->max_texture_height), &map); + + return map; +} + // create_renderer NIF_CALL_HANDLER(thread_create_renderer) @@ -143,6 +180,34 @@ NIF_FUNCTION(get_render_draw_color) NIF_RES_GET(Renderer, renderer_res)); } +// get_render_driver_info +// +// The max_texture_* values will most likely be returned as 0 +// when using this function. The get_renderer_info will always +// have an accurate value on the other hand. + +NIF_CALL_HANDLER(thread_get_render_driver_info) +{ + SDL_RendererInfo info; + + if (SDL_GetRenderDriverInfo((long)args[0], &info)) + return sdl_error_tuple(env); + + return enif_make_tuple2(env, + atom_ok, + renderer_info_to_map(env, &info) + ); +} + +NIF_FUNCTION(get_render_driver_info) +{ + int index; + + BADARG_IF(!enif_get_int(env, argv[0], &index)); + + return nif_thread_call(env, thread_get_render_driver_info, 1, index); +} + // get_render_output_size NIF_CALL_HANDLER(thread_get_render_output_size) @@ -171,6 +236,55 @@ NIF_FUNCTION(get_render_output_size) NIF_RES_GET(Renderer, renderer_res)); } +// get_renderer + +NIF_CALL_HANDLER(thread_get_renderer) +{ + SDL_Renderer* renderer; + + renderer = SDL_GetRenderer(args[0]); + + if (!renderer) + return atom_undefined; + + return esdl2_renderers_find(env, renderer); +} + +NIF_FUNCTION(get_renderer) +{ + void* window_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Window, &window_res)); + + return nif_thread_call(env, thread_get_renderer, 1, + NIF_RES_GET(Window, window_res)); +} + +// get_renderer_info + +NIF_CALL_HANDLER(thread_get_renderer_info) +{ + SDL_RendererInfo info; + + if (SDL_GetRendererInfo(args[0], &info)) + return sdl_error_tuple(env); + + return enif_make_tuple2(env, + atom_ok, + renderer_info_to_map(env, &info) + ); +} + +NIF_FUNCTION(get_renderer_info) +{ + void* renderer_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Renderer, &renderer_res)); + + return nif_thread_call(env, thread_get_renderer_info, 1, + NIF_RES_GET(Renderer, renderer_res)); +} + // render_clear NIF_CALL_HANDLER(thread_render_clear) @@ -617,6 +731,26 @@ NIF_FUNCTION(render_get_clip_rect) NIF_RES_GET(Renderer, renderer_res)); } +// render_get_integer_scale + +NIF_CALL_HANDLER(thread_render_get_integer_scale) +{ + if (SDL_RenderGetIntegerScale(args[0])) + return atom_true; + + return atom_false; +} + +NIF_FUNCTION(render_get_integer_scale) +{ + void* renderer_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Renderer, &renderer_res)); + + return nif_thread_call(env, thread_render_get_integer_scale, 1, + NIF_RES_GET(Renderer, renderer_res)); +} + // render_get_logical_size NIF_CALL_HANDLER(thread_render_get_logical_size) @@ -738,6 +872,28 @@ NIF_FUNCTION(render_set_clip_rect) NIF_RES_GET(Renderer, renderer_res), x, y, w, h); } +// render_set_integer_scale + +NIF_CALL_HANDLER(thread_render_set_integer_scale) +{ + if (SDL_RenderSetIntegerScale(args[0], (long)args[1])) + return sdl_error_tuple(env); + + return atom_ok; +} + +NIF_FUNCTION(render_set_integer_scale) +{ + void* renderer_res; + SDL_bool b; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Renderer, &renderer_res)); + BADARG_IF(!atom_to_bool(env, argv[1], &b)); + + return nif_thread_call(env, thread_render_set_integer_scale, 2, + NIF_RES_GET(Renderer, renderer_res), b); +} + // render_set_logical_size NIF_CALL_HANDLER(thread_render_set_logical_size) -- cgit v1.2.3