summaryrefslogtreecommitdiff
path: root/examples/doom/guest/tinywasm_puredoom.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/doom/guest/tinywasm_puredoom.c')
-rw-r--r--examples/doom/guest/tinywasm_puredoom.c203
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);
+}