diff options
Diffstat (limited to 'examples/doom/guest')
| -rw-r--r-- | examples/doom/guest/tinywasm_puredoom.c | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/examples/doom/guest/tinywasm_puredoom.c b/examples/doom/guest/tinywasm_puredoom.c new file mode 100644 index 0000000..1e3e6bd --- /dev/null +++ b/examples/doom/guest/tinywasm_puredoom.c @@ -0,0 +1,203 @@ +#define DOOM_IMPLEMENTATION +#include "PureDOOM.h" + +#if defined(__clang__) +#define IMPORT(name) __attribute__((import_module("env"), import_name(name))) +#else +#define IMPORT(name) +#endif + +extern int host_open(const char *filename, const char *mode) IMPORT("host_open"); +extern void host_close(int handle) IMPORT("host_close"); +extern int host_read(int handle, void *buf, int count) IMPORT("host_read"); +extern int host_write(int handle, const void *buf, int count) IMPORT("host_write"); +extern int host_seek(int handle, int offset, int origin) IMPORT("host_seek"); +extern int host_tell(int handle) IMPORT("host_tell"); +extern int host_eof(int handle) IMPORT("host_eof"); +extern void host_gettime(int *sec, int *usec) IMPORT("host_gettime"); +extern void host_exit(int code) IMPORT("host_exit"); +extern void host_print(const char *text) IMPORT("host_print"); + +extern unsigned char __heap_base; + +static char g_wad_path[1024]; +static char g_home_dir[] = "."; +static char g_program_name[] = "puredoom"; +static char g_iwad_flag[] = "-iwad"; +static char *g_argv[] = {g_program_name, g_iwad_flag, g_wad_path, 0}; +static unsigned int g_heap_ptr; + +static unsigned int align_up(unsigned int value, unsigned int alignment) +{ + return (value + alignment - 1u) & ~(alignment - 1u); +} + +unsigned int strlen(const char *str) +{ + unsigned int len = 0; + while (str[len] != '\0') + ++len; + return len; +} + +static int str_eq(const char *left, const char *right) +{ + unsigned int i = 0; + for (;;) + { + if (left[i] != right[i]) + return 0; + if (left[i] == '\0') + return 1; + ++i; + } +} + +static void *guest_malloc(int size) +{ + unsigned int alloc_size; + unsigned int end; + unsigned int capacity; + unsigned int extra_pages; + void *result; + + if (size <= 0) + return 0; + + if (g_heap_ptr == 0) + g_heap_ptr = align_up((unsigned int)(unsigned long)&__heap_base, 16u); + + alloc_size = align_up((unsigned int)size, 16u); + end = g_heap_ptr + alloc_size; + capacity = __builtin_wasm_memory_size(0) * 65536u; + + if (end > capacity) + { + extra_pages = (end - capacity + 65535u) / 65536u; + if (__builtin_wasm_memory_grow(0, extra_pages) == (unsigned int)-1) + return 0; + } + + result = (void *)(unsigned long)g_heap_ptr; + g_heap_ptr = end; + return result; +} + +static void guest_free(void *ptr) +{ + (void)ptr; +} + +static void *guest_open(const char *filename, const char *mode) +{ + int handle = host_open(filename, mode); + if (handle < 0) + return 0; + return (void *)(unsigned long)(handle + 1); +} + +static int guest_handle(void *handle) +{ + return (int)(unsigned long)handle - 1; +} + +static void guest_close(void *handle) +{ + host_close(guest_handle(handle)); +} + +static int guest_read(void *handle, void *buf, int count) +{ + return host_read(guest_handle(handle), buf, count); +} + +static int guest_write(void *handle, const void *buf, int count) +{ + return host_write(guest_handle(handle), buf, count); +} + +static int guest_seek(void *handle, int offset, doom_seek_t origin) +{ + return host_seek(guest_handle(handle), offset, (int)origin); +} + +static int guest_tell(void *handle) +{ + return host_tell(guest_handle(handle)); +} + +static int guest_eof(void *handle) +{ + return host_eof(guest_handle(handle)); +} + +static void guest_gettime(int *sec, int *usec) +{ + host_gettime(sec, usec); +} + +static void guest_exit(int code) +{ + host_exit(code); +} + +static char *guest_getenv(const char *var) +{ + if (str_eq(var, "HOME")) + return g_home_dir; + return 0; +} + +unsigned int tinywasm_doom_wad_path_buf(void) +{ + return (unsigned int)(unsigned long)g_wad_path; +} + +void tinywasm_doom_init(void) +{ + doom_set_print(host_print); + doom_set_malloc(guest_malloc, guest_free); + doom_set_file_io(guest_open, guest_close, guest_read, guest_write, guest_seek, guest_tell, guest_eof); + doom_set_gettime(guest_gettime); + doom_set_exit(guest_exit); + doom_set_getenv(guest_getenv); + + doom_set_default_int("key_up", DOOM_KEY_W); + doom_set_default_int("key_down", DOOM_KEY_S); + doom_set_default_int("key_strafeleft", DOOM_KEY_A); + doom_set_default_int("key_straferight", DOOM_KEY_D); + doom_set_default_int("key_use", DOOM_KEY_E); + doom_set_resolution(320, 200); + + doom_init(3, g_argv, DOOM_FLAG_HIDE_MOUSE_OPTIONS | DOOM_FLAG_HIDE_SOUND_OPTIONS | DOOM_FLAG_HIDE_MUSIC_OPTIONS); +} + +void tinywasm_doom_update(void) +{ + doom_update(); +} + +unsigned int tinywasm_doom_framebuffer(void) +{ + return (unsigned int)(unsigned long)doom_get_framebuffer(4); +} + +unsigned int tinywasm_doom_sound_buffer(void) +{ + return (unsigned int)(unsigned long)doom_get_sound_buffer(); +} + +unsigned long tinywasm_doom_tick_midi(void) +{ + return doom_tick_midi(); +} + +void tinywasm_doom_key_down(int key) +{ + doom_key_down((doom_key_t)key); +} + +void tinywasm_doom_key_up(int key) +{ + doom_key_up((doom_key_t)key); +} |
