diff options
| author | Nicholas Tay <nick@windblume.net> | 2022-05-10 00:40:10 +1000 | 
|---|---|---|
| committer | Nicholas Tay <nick@windblume.net> | 2022-05-10 00:47:38 +1000 | 
| commit | 6a1e6a7d6b6a3d987f2fccb3c06f4f5da071f504 (patch) | |
| tree | 3899a31897c01323fb5d896b08412aa45e939885 | |
| parent | 5270088f730a7e30155a642dcd5c4e9a80055d7a (diff) | |
| download | clak-6a1e6a7d6b6a3d987f2fccb3c06f4f5da071f504.tar.gz clak-6a1e6a7d6b6a3d987f2fccb3c06f4f5da071f504.tar.bz2 clak-6a1e6a7d6b6a3d987f2fccb3c06f4f5da071f504.zip | |
Dynamic load boards as DLL (windows only for now)
The .h files are pretty weird, should look at other C projects to see
how they load plugins. This function pointer business with typedefs is
kinda weird, not sure where they should live.
Diffstat (limited to '')
| -rw-r--r-- | .gitignore | 4 | ||||
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | board/Makefile | 32 | ||||
| -rw-r--r-- | board/board.c | 8 | ||||
| -rw-r--r-- | board/board.h | 12 | ||||
| -rw-r--r-- | board/generate.sh | 8 | ||||
| -rw-r--r-- | board/mxblue/board.c | 12 | ||||
| -rw-r--r-- | board/mxblue/board.h | 3 | ||||
| -rw-r--r-- | board/quack/board.c | 12 | ||||
| -rw-r--r-- | board/quack/board.h | 3 | ||||
| -rw-r--r-- | board/simple.h | 9 | ||||
| -rw-r--r-- | boards.h | 6 | ||||
| -rw-r--r-- | clak.c | 58 | ||||
| -rw-r--r-- | clak.h | 8 | ||||
| -rw-r--r-- | platform/platform.h | 5 | ||||
| -rw-r--r-- | platform/win32.c | 38 | 
16 files changed, 149 insertions, 71 deletions
| @@ -1,4 +1,6 @@  clak  clak.exe  board/boards.h -board/*/sound.h
\ No newline at end of file +board/*/sound.h +board/*.dll +board/*.so
\ No newline at end of file @@ -16,7 +16,7 @@ endif  default: $(NAME) -$(NAME): $(NAME).c platform/$(PLATFORM).c boards.h +$(NAME): $(NAME).c platform/$(PLATFORM).c  	$(CC) $(CFLAGS) $(NAME).c platform/$(PLATFORM).c $(LDLIBS) -o $(NAME)  clean: diff --git a/board/Makefile b/board/Makefile new file mode 100644 index 0000000..24cb10c --- /dev/null +++ b/board/Makefile @@ -0,0 +1,32 @@ +BOARDS = mxblue quack + +CC = gcc +CFLAGS += -std=c99 -Wall -Wextra -Wshadow -Werror -pedantic -shared + +ifeq ($(OS),Windows_NT) +    OUTEXT = dll +else +    OUTEXT = so +endif + +default: all +all: $(BOARDS) + +# TODO: use "BOARDS" variable to generate this. +# TODO: have some preset for 'simple' board type? also in the c file. +mxblue: mxblue.$(OUTEXT) +quack: quack.$(OUTEXT) +mxblue.$(OUTEXT): mxblue/board.c mxblue/sound.h +	$(CC) $(CFLAGS) mxblue/board.c -o mxblue.$(OUTEXT) +quack.$(OUTEXT): quack/board.c quack/sound.h +	$(CC) $(CFLAGS) quack/board.c -o quack.$(OUTEXT) +mxblue/sound.h: +	xxd -i mxblue/board_down.wav mxblue/sound.h +quack/sound.h: +	xxd -i quack/board_down.wav quack/sound.h + +clean: +	rm -f *.o +	rm -f *.dll +	rm -f *.so +	rm -f */sound.h
\ No newline at end of file diff --git a/board/board.c b/board/board.c new file mode 100644 index 0000000..0410aef --- /dev/null +++ b/board/board.c @@ -0,0 +1,8 @@ +#include "board.h" + +static fn_sound_play sound_play; + +void board_init(fn_sound_play sp) +{ +    sound_play = sp; +}
\ No newline at end of file diff --git a/board/board.h b/board/board.h new file mode 100644 index 0000000..18f6afa --- /dev/null +++ b/board/board.h @@ -0,0 +1,12 @@ +#ifndef CLAK_BOARD_H_ +#define CLAK_BOARD_H_ + +#include <stdbool.h> + +#include "../clak.h" + +typedef void (*fn_board_init)(fn_sound_play sp); +typedef void (*fn_board_on_down)(void); +typedef void (*fn_board_on_up)(void); + +#endif /* CLAK_BOARD_H_ */
\ No newline at end of file diff --git a/board/generate.sh b/board/generate.sh deleted file mode 100644 index 6d8d593..0000000 --- a/board/generate.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -BOARDS='mxblue quack' - -cd "$(dirname "$0")" -for board in $BOARDS; do -	xxd -i $board/board_down.wav $board/sound.h -done
\ No newline at end of file diff --git a/board/mxblue/board.c b/board/mxblue/board.c new file mode 100644 index 0000000..14277db --- /dev/null +++ b/board/mxblue/board.c @@ -0,0 +1,12 @@ +#include "sound.h" + +#include "../board.c" + +void board_on_down(void) +{ +	sound_play(mxblue_board_down_wav); +} + +void board_on_up(void) +{ +}
\ No newline at end of file diff --git a/board/mxblue/board.h b/board/mxblue/board.h deleted file mode 100644 index 7d17f3f..0000000 --- a/board/mxblue/board.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "./sound.h" -#include "../simple.h" -SIMPLE_BOARD(mxblue)
\ No newline at end of file diff --git a/board/quack/board.c b/board/quack/board.c new file mode 100644 index 0000000..893e366 --- /dev/null +++ b/board/quack/board.c @@ -0,0 +1,12 @@ +#include "sound.h" + +#include "../board.c" + +void board_on_down(void) +{ +	sound_play(quack_board_down_wav); +} + +void board_on_up(void) +{ +}
\ No newline at end of file diff --git a/board/quack/board.h b/board/quack/board.h deleted file mode 100644 index 64ba4cb..0000000 --- a/board/quack/board.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "./sound.h" -#include "../simple.h" -SIMPLE_BOARD(quack)
\ No newline at end of file diff --git a/board/simple.h b/board/simple.h deleted file mode 100644 index c2b211b..0000000 --- a/board/simple.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef CLAK_SIMPLE_H_ -#define CLAK_SIMPLE_H_ - -extern void sound_play(unsigned char *buffer); -#define SIMPLE_BOARD(name) \ -	void name ## _on_down(void) { sound_play( name ## _board_down_wav ); } \ -	void name ## _on_up(void) { sound_play( name ## _board_down_wav ); } - -#endif /* CLAK_SIMPLE_H_ */
\ No newline at end of file diff --git a/boards.h b/boards.h deleted file mode 100644 index 9090570..0000000 --- a/boards.h +++ /dev/null @@ -1,6 +0,0 @@ -#include "board/mxblue/board.h" -#include "board/quack/board.h" - -#define BOARDS \ -	BOARD(mxblue) \ -	BOARD(quack) @@ -1,37 +1,13 @@  #include <stdio.h>  #include <unistd.h>  #include <string.h> -#include <stdbool.h>  #include <stdlib.h> -#define VOLUME 0.15 - -#define BOARD(x) { .name = #x, .on_down = x ## _on_down, .on_up = x ## _on_up }, -#include "boards.h" - +#include "clak.h"  #include "platform/platform.h" +#include "board/board.h" -typedef struct { -	char *name; -	void (*on_down)(void); -	void (*on_up)(void); -} Board; - -Board boards[] = { -	BOARDS -}; -int const boards_n = sizeof(boards) / sizeof(boards[0]); - -Board *board = NULL; - -Board *get_board(char *board_name) -{ -	for (int i = 0; i < boards_n; ++i) { -		if (strcmp(boards[i].name, board_name) == 0) -			return &boards[i]; -	} -	return NULL; -} +#define VOLUME 0.15  void do_exit(int code)  { @@ -41,30 +17,32 @@ void do_exit(int code)  }  void on_clean_exit(void) { do_exit(0); } +fn_board_on_down board_on_down; +fn_board_on_up board_on_up; +  void keyboard_on_down(void)  { -	if (board == NULL) -		return; -	board->on_down(); +	board_on_down();  }  void keyboard_on_up(void)  { -	if (board == NULL) -		return; -	board->on_up(); +	board_on_up();  }  int main(int argc, char **argv)  { -	if (argc < 2 || (board = get_board(argv[1])) == NULL) { -		printf("Please provide a valid board name.\n"); -		printf("Valid boards: "); -		for (int i = 0; i < boards_n; ++i) { -			printf("%s%s", boards[i].name, (i == boards_n - 1) ? "\n" : ", "); -		} +	fprintf(stderr, "Clak: This is Clak, Nicholas Tay, version: 0.1.0.\n"); + +	if (argc < 2) { +		printf("ERROR: Please provide a board name.\n"); +		// TODO: List valid boards. +		return 1; +	} +	if (!load_board(argv[1], &board_on_down, &board_on_up)) {  		return 1;  	} +	fprintf(stderr, "Loaded board: %s\n", argv[1]);  	if (!sound_init(VOLUME)) {  		printf("ERROR: Could not initialise sound system.\n"); @@ -75,7 +53,7 @@ int main(int argc, char **argv)  		return 1;  	}  	atexit(on_clean_exit); -	fprintf(stderr, "Hooks set up, welcome to Clak!\n"); +	fprintf(stderr, "Hooks set up, enjoy your stay!\n");  	enter_idle(); @@ -0,0 +1,8 @@ +#ifndef CLAK_H_ +#define CLAK_H_ + +#include <stdbool.h> + +typedef void (*fn_sound_play)(unsigned char *buffer); + +#endif /* CLAK_H_ */
\ No newline at end of file diff --git a/platform/platform.h b/platform/platform.h index da1efa6..fd9b9bb 100644 --- a/platform/platform.h +++ b/platform/platform.h @@ -1,6 +1,11 @@  #ifndef CLAK_PLATFORM_H_  #define CLAK_PLATFORM_H_ +#include <stdbool.h> + +#include "../board/board.h" + +bool load_board(char *board_name, fn_board_on_down *on_down, fn_board_on_down *on_up);  bool sound_init(float volume);  void sound_play(unsigned char *buffer);  void keyboard_unhook(void); diff --git a/platform/win32.c b/platform/win32.c index 90cd37c..cf22718 100644 --- a/platform/win32.c +++ b/platform/win32.c @@ -2,6 +2,9 @@  #include <stdbool.h>  #include <windows.h> +#include "platform.h" +#include "../board/board.h" +  /* Required callbacks */  extern void keyboard_on_down(void);  extern void keyboard_on_up(void); @@ -77,4 +80,39 @@ void enter_idle(void)  			exit(1);  		}  	} +} + +bool load_board(char *board_name, fn_board_on_down *on_down, fn_board_on_down *on_up) +{ +	char dll_name[100]; +	int r = snprintf(dll_name, 100, "./board/%s.dll", board_name); +	if (r < 0 || r >= 100) { +		printf("ERROR: Invalid board name.\n"); +		return false; +	} + +	HMODULE board_module = LoadLibrary(dll_name); +	if (board_module == NULL) { +		printf("ERROR: Could not load board module.\n"); +		return false; +	} +	fn_board_init board_init = (fn_board_init) (void (*)(void)) GetProcAddress(board_module, "board_init"); +	if (board_init == NULL) { +		printf("ERROR: No board down function could be loaded.\n"); +		return false; +	} +	board_init(&sound_play); + +	*on_down = (fn_board_on_down) GetProcAddress(board_module, "board_on_down"); +	if (on_down == NULL) { +		printf("ERROR: No board down function could be loaded.\n"); +		return false; +	} +	*on_up = (fn_board_on_up) GetProcAddress(board_module, "board_on_up"); +	if (on_up == NULL) { +		printf("ERROR: No board up function could be loaded.\n"); +		return false; +	} + +	return true;  }
\ No newline at end of file | 
