--- /dev/null
+/*
+ * bcm_host_shim
+ * (C) notaz, 2016
+ *
+ * This work is licensed under the terms of 3-clause BSD license.
+ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <dlfcn.h>
+
+#define SCREEN_WIDTH 800
+#define SCREEN_HEIGHT 480
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+
+void bcm_host_init(void)
+{
+}
+
+void bcm_host_deinit(void)
+{
+}
+
+uint32_t vc_dispmanx_display_open(uint32_t dev)
+{
+ return 0xf00;
+}
+
+uint32_t vc_dispmanx_element_add()
+{
+ return 0xf04;
+}
+
+uint32_t vc_dispmanx_update_start(int32_t prio)
+{
+ return 0xf08;
+}
+
+int vc_dispmanx_update_submit_sync(uint32_t upd_handle)
+{
+ //printf("%s\n", __func__);
+ return 0;
+}
+
+int graphics_get_display_size(uint16_t dpy, uint32_t *w, uint32_t *h)
+{
+ *w = SCREEN_WIDTH;
+ *h = SCREEN_HEIGHT;
+ return 0;
+}
+
+#ifndef SDL_FULLSCREEN
+#define SDL_FULLSCREEN 0x80000000
+#define SDL_RESIZABLE 0x00000010
+#endif
+
+static void *get_real_func(const char *name)
+{
+ void *f;
+
+ f = dlsym(RTLD_NEXT, name);
+ if (f == NULL) {
+ fprintf(stderr, "%s: %s\n", name, dlerror());
+ _exit(1);
+ }
+ return f;
+}
+
+/* pandora's SGX driver can only run fullscreen */
+void *SDL_SetVideoMode(int width, int height, int bpp, uint32_t flags)
+{
+ static void * (*f)(int, int, int, uint32_t);
+
+ //printf("%s %d %x\n", __func__, bpp, flags);
+
+ width = height = bpp = 0;
+ flags &= ~SDL_RESIZABLE;
+ flags |= SDL_FULLSCREEN;
+
+ if (f == NULL)
+ f = get_real_func(__func__);
+
+ return f(width, height, bpp, flags);
+}
+
+int SDL_PollEvent(void *e)
+{
+ static int (*f)(void *);
+ int ret;
+
+ if (f == NULL)
+ f = get_real_func(__func__);
+
+ ret = f(e);
+
+ // event, SDL_KEYDOWN, SDLK_q
+ if (ret != 0 && e != NULL) {
+ if (*(uint8_t *)e == 2 && ((uint32_t *)e)[2] == 113)
+ *(uint8_t *)e = 12; // SDL_QUIT
+ }
+
+ return ret;
+}
+
+/* can't use 8bits/channel on pandora, must filter out confing */
+#ifndef EGL_NONE
+#define EGL_NONE 0x3038
+#define EGL_RED_SIZE 0x3024
+#define EGL_GREEN_SIZE 0x3023
+#define EGL_BLUE_SIZE 0x3022
+#define EGL_ALPHA_SIZE 0x3021
+#define EGL_SURFACE_TYPE 0x3033
+#endif
+
+int eglChooseConfig(void *dpy, const int32_t *attrib_list,
+ void *configs, int32_t config_size, int32_t *num_config)
+{
+ static int (*f)(void *, const int32_t *,
+ void *, int32_t, int32_t *);
+ int32_t attrib_list_c[64];
+ int i, o;
+
+ //printf("%s\n", __func__);
+
+ if (f == NULL)
+ f = get_real_func(__func__);
+
+ for (i = o = 0; o < ARRAY_SIZE(attrib_list_c) - 2; i += 2) {
+ if (attrib_list == NULL || attrib_list[i] == EGL_NONE)
+ break;
+
+ switch (attrib_list[i]) {
+ case EGL_RED_SIZE:
+ case EGL_GREEN_SIZE:
+ case EGL_BLUE_SIZE:
+ case EGL_SURFACE_TYPE:
+ case EGL_ALPHA_SIZE:
+ continue;
+ }
+
+ attrib_list_c[o++] = attrib_list[i + 0];
+ attrib_list_c[o++] = attrib_list[i + 1];
+ }
+ attrib_list_c[o++] = EGL_NONE;
+
+ return f(dpy, attrib_list_c, configs, config_size, num_config);
+}
+
+void *eglCreateWindowSurface(void *dpy, void *config, void *win,
+ const int32_t *attrib_list)
+{
+ static void * (*f)(void *, void *, void *, const int32_t *);
+
+ //printf("%s\n", __func__);
+
+ if (f == NULL)
+ f = get_real_func(__func__);
+
+ return f(dpy, config, NULL, attrib_list);
+}