part: add mlx_hook.h functions

This commit is contained in:
Zy 2024-10-13 19:38:36 +02:00
parent a93af5c48f
commit cca1adca0c
8 changed files with 405 additions and 26 deletions

View file

@ -40,6 +40,47 @@ static void draw_rainbow_image(t_mlx mlx, t_win win, int x, int y)
}
}
static int keydown_hook(int keycode, void *param)
{
(void)param;
cout << "[D" << keycode << "] (B to continue)" << endl;
return (0);
};
static int create_hook(void *param) {
(void)param;
cout << "create_hook() called" << endl;
int file = open("__tmp_heya.txt", O_RDONLY);
if (!file)
cout << "can't open file __tmp_heya.txt" << endl;
else {
static char buf[100];
if (read(file, buf, 100) < 0)
cout << "can't read file" << endl;
else
cout << "buf :\"" << buf << "\"" << endl;
}
close(file);
cout
<< "quit software to create file:" << endl
<< " __tmp_heya.txt" << endl;
return (0);
};
static int destroy_hook(void **ptrs) {
int file = open("__tmp_heya.txt", O_WRONLY | O_CREAT);
if (!file) {
cout << "can't create file" << endl;
return (0);
}
write(file, "spaghetti :3\n", 13);
if (!file)
cout << "can't write on file" << endl;
close(file);
mlx_loop_end(ptrs[0]);
return (0);
};
int main(void) {
void *const mlx = mlx_init();
void *win;
@ -47,7 +88,7 @@ int main(void) {
// MENU
{
switch (uc_menu_quick("pixels", "images", "xpm", "files",
"navigate", "assets", "xpm files", "quit", NULL))
"navigate", "assets", "xpm files", "events", "quit", NULL))
{
case 0:
goto pixels;
@ -70,6 +111,9 @@ int main(void) {
case 6:
goto xpm_files;
break;
case 7:
goto events;
break;
}
goto end;
}
@ -582,6 +626,59 @@ xpm_files:
}
goto end;
events:
{
win = mlx_new_window(mlx, 400, 240, NULL);
const static auto loop_hook = [](void *param) -> int {
(void)param;
cout << "hi from loop_hook (B to continue)" << endl;
hidScanInput();
if (hidKeysDown() & KEY_B)
mlx_loop_end(param);
return (0);
};
mlx_loop_hook(mlx, loop_hook, mlx);
mlx_loop(mlx);
cout << "mlx_loop() returned." << endl;
mlx_destroy_window(mlx, win);
mlx_loop_hook(mlx, NULL, NULL);
uc_pause();
}
{
win = mlx_new_window(mlx, 400, 240, NULL);
const static auto key_hook = [](int keycode, void *param) -> int {
cout << "[U" << keycode << "] (B to continue)" << endl;
if (keycode == KEY_B)
mlx_loop_end(param);
return (0);
};
mlx_key_hook(win, key_hook, mlx);
mlx_hook(win, KeyPress, 0, (int (*)())(void *)&keydown_hook, mlx);
mlx_loop(mlx);
cout << "mlx_loop() returned." << endl;
mlx_destroy_window(mlx, win);
uc_pause();
}
{
win = mlx_new_window(mlx, 400, 240, NULL);
void *ptrs[2];
ptrs[0] = mlx;
ptrs[1] = win;
mlx_hook(win, CreateNotify, 0, (int (*)())(void *)&create_hook, NULL);
mlx_hook(win, DestroyNotify, 0, (int (*)())(void *)&destroy_hook, &ptrs);
mlx_loop(mlx);
cout << "mlx_loop() returned." << endl;
mlx_destroy_window(mlx, win);
uc_pause();
}
goto end;
end:
cout << "Exit..." << endl;
uc_pause();

135
source/mlx_hook.c Normal file
View file

@ -0,0 +1,135 @@
/**
* mlx_hook.c
* for the project "MinilibX for 3DS"
* by Zy
* at https://github.com/frzysk/mlx3ds
*/
#include "mlx_hook.h"
#include "mlx_internal.h"
int mlx_mouse_hook(t_win win_ptr, int (*funct_ptr)(), void *param)
{
(void)win_ptr;
(void)funct_ptr;
(void)param;
// ╮(︶▽︶)╭
return (0);
}
int mlx_key_hook(t_win win_ptr,
int (*funct_ptr)(int keycode, void *param), void *param)
{
((t_internal_win *)win_ptr)->hooks[KeyRelease].hook = funct_ptr;
((t_internal_win *)win_ptr)->hooks[KeyRelease].param = param;
return (0);
}
int mlx_expose_hook(t_win win_ptr,
int (*funct_ptr)(void *param), void *param)
{
// TODO use expose hook?
((t_internal_win *)win_ptr)->hooks[Expose].hook = funct_ptr;
((t_internal_win *)win_ptr)->hooks[Expose].param = param;
return (0);
}
#include <stdlib.h> // remove debug TODO
#include <stdio.h>
#include "utilsconsole.h"
int mlx_loop_hook(t_mlx mlx_ptr,
int (*funct_ptr)(void *param), void *param)
{
((t_internal_mlx *)mlx_ptr)->hook_loop_function = funct_ptr;
((t_internal_mlx *)mlx_ptr)->hook_loop_param = param;
return (0);
}
int mlx_hook(t_win win_ptr, int x_event, int x_mask,
int (*funct)(), void *param)
{
(void)x_mask;
((t_internal_win *)win_ptr)->hooks[x_event].hook = funct;
((t_internal_win *)win_ptr)->hooks[x_event].param = param;
return (0);
}
typedef struct
{
u32 held;
u32 down;
u32 up;
} t_keys_status;
static t_keys_status keys_events(void)
{
static u32 last_held;
static u32 real_last_held;
t_keys_status r;
u32 real_held = hidKeysHeld();
hidScanInput();
r.held = real_held | real_last_held;
r.up = last_held & ~r.held;
r.down = ~last_held & r.held;
last_held = r.held;
real_last_held = real_held;
return (r);
}
static void call_events(t_internal_win *win, t_keys_status keys)
{
if (win->hooks[KeyRelease].hook && keys.up)
for (int i = 0; i < 32; i++)
if ((keys.up >> i) & 1)
win->hooks[KeyRelease].hook(
1 << i, win->hooks[KeyRelease].param);
if (win->hooks[KeyPress].hook && keys.down)
for (int i = 0; i < 32; i++)
if ((keys.down >> i) & 1)
win->hooks[KeyPress].hook(
1 << i, win->hooks[KeyPress].param);
}
static void call_start_events(t_internal_win *win)
{
if (win->hooks[CreateNotify].hook)
win->hooks[CreateNotify].hook(win->hooks[CreateNotify].param);
}
static void call_end_events(t_internal_win *win)
{
if (win->hooks[DestroyNotify].hook)
win->hooks[DestroyNotify].hook(win->hooks[DestroyNotify].param);
}
int mlx_loop(t_mlx mlx_ptr)
{
t_internal_mlx *mlx = mlx_ptr;
mlx->loop = true;
if (mlx->top_window)
call_start_events(mlx->top_window);
while (aptMainLoop() && mlx->loop)
{
t_keys_status keys = keys_events();
if (mlx->top_window)
call_events(mlx->top_window, keys);
if (mlx->hook_loop_function)
mlx->hook_loop_function(mlx->hook_loop_param);
gfxFlushBuffers(); // aptMainLoop() doesn't work without that
}
if (!aptMainLoop())
if (mlx->top_window)
call_end_events(mlx->top_window);
mlx->loop = false;
return (0);
}
int mlx_loop_end(t_mlx mlx_ptr)
{
((t_internal_mlx *)mlx_ptr)->loop = false;
return (0);
}

View file

@ -11,10 +11,7 @@
#include <stdlib.h>
#include "3ds.h"
static t_internal_mlx g_internal_mlx = {
.is_init_called = false,
.top_window = NULL,
};
static t_internal_mlx g_internal_mlx;
t_mlx mlx_init(void)
{

View file

@ -14,6 +14,7 @@
# include <stdbool.h>
# include "3ds.h"
# include "mlx_events.h"
/// @brief Write an error message and exit the program.
///
@ -29,23 +30,38 @@ typedef struct s_internal_mlx
bool is_init_called;
/// @brief Window displayed on the top screen.
struct s_internal_win *top_window;
/// @brief Function called in loop by mlx_loop().
int (*hook_loop_function)(void *param);
/// @brief Parameter given to hook_loop_function.
void *hook_loop_param;
/// @brief Set to false to break the loop of mlx_loop().
bool loop;
} t_internal_mlx;
// TODO docs
typedef struct s_internal_win_hook
{
int (*hook)();
void *param;
} t_internal_win_hook;
/// @brief Represents a window.
typedef struct s_internal_win
{
/// @brief mlx connection identifier
t_internal_mlx *mlx;
t_internal_mlx *mlx;
/// @brief Width of the window
int width;
int width;
/// @brief Height of the window
int height;
int height;
/// @brief Buffer of the screen.
u8 *framebuffer;
u8 *framebuffer;
/// @brief Width of the screen (on x).
u16 framebuffer_width;
u16 framebuffer_width;
/// @brief Height of the screen (on y).
u16 framebuffer_height;
u16 framebuffer_height;
// TODO docs
t_internal_win_hook hooks[LASTEvent];
} t_internal_win;
/// @brief Represents an image in memory.

View file

@ -10,6 +10,7 @@
#include "3ds.h"
#include "mlx_internal.h"
#include <stdlib.h>
#include <strings.h>
t_win mlx_new_window(t_mlx mlx_ptr, int size_x, int size_y, const char *title)
{
@ -21,10 +22,11 @@ t_win mlx_new_window(t_mlx mlx_ptr, int size_x, int size_y, const char *title)
r = malloc(sizeof(t_internal_win));
if (!r)
return (NULL);
bzero(r, sizeof(t_internal_win));
r->mlx = mlx_ptr;
r->mlx->top_window = r;
r->width = size_x;
r->height = size_y;
r->framebuffer = NULL;
return (r);
}