/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* mlx.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: smaccary +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/07/31 17:45:21 by smaccary #+# #+# */ /* Updated: 2020/07/31 17:45:21 by smaccary ### ########.fr */ /* */ /* ************************************************************************** */ #include "mlx_int.h" #include static void init_X11_events_map(uint32_t *map) { map[KeyPress] = SDL_KEYDOWN; map[KeyRelease] = SDL_KEYUP; map[ButtonPress] = SDL_MOUSEBUTTONDOWN; map[ButtonRelease] = SDL_MOUSEBUTTONUP; map[FocusIn] = SDL_WINDOWEVENT_FOCUS_GAINED; map[FocusOut] = SDL_WINDOWEVENT_FOCUS_LOST; map[DestroyNotify] = SDL_WINDOWEVENT_CLOSE; map[Expose] = SDL_WINDOWEVENT_EXPOSED; } static uint32_t get_mlx_event(uint32_t *map, uint32_t sdl_event) { uint32_t i; i = -1; while (++i < MLX_MAX_EVENT) { if (map[i] == sdl_event) return (i); } return (0); } void *mlx_init() { t_sdl_var *mlx; mlx = calloc(1, sizeof(t_sdl_var)); SDL_Init(SDL_INIT_EVERYTHING); init_X11_events_map(mlx->X11_event_map); return (mlx); } void *mlx_new_image(t_sdl_var *mlx_ptr, int width, int height) { (void)mlx_ptr; return (SDL_CreateRGBSurface(0, width, height, BITS_PER_PIXELS, 0, 0, 0, 0)); } void *mlx_new_window(t_sdl_var *mlx_ptr, int size_x, int size_y, char *title) { t_sdl_win *win; win = calloc(1, sizeof(t_sdl_win)); win->win_ptr = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, size_x, size_y, 0); win->renderer = SDL_CreateRenderer(win->win_ptr, 1, SDL_RENDERER_ACCELERATED); win->width = size_x; win->height = size_y; win->text = SDL_CreateTexture(win->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, win->width, win->height); ft_lstadd_front(&(mlx_ptr->win_list), ft_lstnew(win)); win->mlx_ptr = mlx_ptr; return (win); } char *mlx_get_data_addr(SDL_Surface *img_ptr, int *bits_per_pixel, int *size_line, int *endian) { *bits_per_pixel = img_ptr->format->BitsPerPixel; *size_line = img_ptr->pitch; *endian = 0; return ((char *)(img_ptr->pixels)); } /* ** I've not tested this one but it should work, i hope */ int mlx_pixel_put(t_sdl_var *mlx_ptr, t_sdl_win *win_ptr, int x, int y, uint32_t color) { SDL_Rect rect; (void)mlx_ptr; rect = (SDL_Rect){.x = x, .y =y, .w = 1, .h = 1}; SDL_UpdateTexture(win_ptr->text, &rect, &color, sizeof(uint32_t)); SDL_RenderClear(win_ptr->renderer); SDL_RenderCopy(win_ptr->renderer, win_ptr->text, NULL, NULL); SDL_RenderPresent(win_ptr->renderer); return (1); } int mlx_put_image_to_window(t_sdl_var *mlx_ptr, t_sdl_win *win_ptr, SDL_Surface *img_ptr, int x, int y) { SDL_Rect rect; (void)mlx_ptr; rect = (SDL_Rect){.w = img_ptr->w, .h = img_ptr->h, .x = x, .y = y}; SDL_UpdateTexture(win_ptr->text, &rect, img_ptr->pixels, img_ptr->pitch); SDL_RenderClear(win_ptr->renderer); SDL_RenderCopy(win_ptr->renderer, win_ptr->text, NULL, NULL); SDL_RenderPresent(win_ptr->renderer); return (1); } int mlx_clear_window(t_sdl_var *mlx_ptr, t_sdl_win *win_ptr) { (void)mlx_ptr; SDL_RenderClear(win_ptr->renderer); return (1); } int mlx_destroy_image(t_sdl_var *mlx_ptr, SDL_Surface *img_ptr) { (void)mlx_ptr; SDL_FreeSurface(img_ptr); return (1); } int mlx_destroy_window(t_sdl_var *mlx_ptr, t_sdl_win *win_ptr) { SDL_DestroyWindow(win_ptr->win_ptr); SDL_DestroyRenderer(win_ptr->renderer); SDL_DestroyTexture(win_ptr->text); ft_lstdelone(ft_lstchr(mlx_ptr->win_list, win_ptr), NULL); return (1); } SDL_Surface *mlx_xpm_file_to_image(t_sdl_var *mlx_ptr, char *filename, int *width, int *height) { SDL_RWops *rwop; SDL_Surface *src; SDL_Surface *img; SDL_PixelFormat fmt; (void)mlx_ptr; if(!(rwop = SDL_RWFromFile(filename, "rb"))) return (NULL); if (!(src = IMG_Load_RW(rwop, 0))) { printf("IMG_Load_RW: %s on file %s\n", IMG_GetError(), filename); SDL_FreeRW(rwop); return (NULL); } fmt = (SDL_PixelFormat) { .BitsPerPixel = BITS_PER_PIXELS, .BytesPerPixel = BITS_PER_PIXELS / 8 }; img = SDL_ConvertSurface(src, &fmt, 0); SDL_FreeRW(rwop); SDL_FreeSurface(src); *width = img->w; *height = img->h; return (img); } int mlx_hook(t_sdl_win *win_ptr, int x_event, int x_mask, int (*funct)(), void *param) { t_sdl_var *mlx; mlx = win_ptr->mlx_ptr; mlx->hooks[x_event].hook = funct; mlx->hooks[x_event].param = param; mlx->hooks[x_event].mask = x_mask; return (1); } int mlx_loop_hook(t_sdl_var *mlx_ptr, int (*funct_ptr)(), void *param) { mlx_ptr->loop_hook = funct_ptr; mlx_ptr->loop_param = param; return (1); } int mlx_key_hook(void *win_ptr, int (*funct_ptr)(), void *param) { return (mlx_hook(win_ptr, KeyPress, KeyPressMask, funct_ptr, param)); } int mlx_mouse_get_pos(void *mlx_ptr, void *win_ptr, int *x, int *y) { (void)win_ptr; (void)mlx_ptr; return (SDL_GetMouseState(x, y)); } int mlx_mouse_move(t_sdl_var *mlx_ptr, t_sdl_win *win_ptr, int x, int y) { (void)mlx_ptr; SDL_WarpMouseInWindow(win_ptr->win_ptr , x, y); return (1); } int mlx_mouse_show(t_sdl_var *mlx_ptr, t_sdl_win *win_ptr) { (void)mlx_ptr; (void)win_ptr; return (SDL_ShowCursor(SDL_ENABLE)); } int mlx_mouse_hide(t_sdl_var *mlx_ptr, t_sdl_win *win_ptr) { (void)mlx_ptr; (void)win_ptr; return (SDL_ShowCursor(SDL_DISABLE)); } int mlx_get_screen_size(t_sdl_var *mlx_ptr, int *sizex, int *sizey) { SDL_DisplayMode dm; (void)mlx_ptr; if (SDL_GetDesktopDisplayMode(0, &dm) != 0) { SDL_Log("SDL_GetDesktopDisplayMode failed: %s", SDL_GetError()); return 1; } *sizex = dm.w; *sizey = dm.h; return (1); } int mlx_do_key_autorepeatoff(t_sdl_var *mlx_ptr) { return ((mlx_ptr->autorepeat = 0)); } int mlx_do_key_autorepeaton(t_sdl_var *mlx_ptr) { return ((mlx_ptr->autorepeat = 1)); } int mlx_mouse_hook(t_sdl_win *win_ptr, int (*funct_ptr)(), void *param) { t_sdl_var *mlx; mlx = win_ptr->mlx_ptr; mlx->mouse_hook = funct_ptr; mlx->mouse_param = param; return (1); } int mlx_expose_hook (t_sdl_win *win_ptr, int (*funct_ptr)(), void *param) { return (mlx_hook(win_ptr, Expose, ExposureMask, funct_ptr, param)); } #include "../SDL/include/SDL2/SDL.h" int mlx_loop (t_sdl_var *mlx_ptr) { SDL_Event sdl_event; t_mlx_event *mlx_event; uint32_t event_type; int (*hook)(); while (42) { while (SDL_PollEvent(&sdl_event)) { event_type = sdl_event.type; if (event_type == SDL_WINDOWEVENT) event_type = sdl_event.window.event; mlx_event = mlx_ptr->hooks + get_mlx_event(mlx_ptr->X11_event_map, event_type); hook = mlx_event->hook; if (hook) { if (SDL_MOUSEBUTTONDOWN <= event_type && event_type <= SDL_MOUSEBUTTONUP) { hook(sdl_event.button.button, sdl_event.button.x, sdl_event.button.y, mlx_event->param); if (mlx_ptr->mouse_hook) (mlx_ptr->mouse_hook)(sdl_event.button.button, sdl_event.button.x, sdl_event.button.y, mlx_ptr->mouse_param); } else if ((SDL_KEYDOWN <= event_type && event_type <= SDL_KEYUP)) { if ((!(sdl_event.key.repeat) || mlx_ptr->autorepeat)) hook((int)sdl_event.key.keysym.sym, mlx_event->param); } else hook(mlx_event->param); } } if (mlx_ptr->loop_hook) mlx_ptr->loop_hook(mlx_ptr->loop_param); } }