mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-27 02:00:41 +00:00
initial emscripten port (no audio/files, input broken)
This commit is contained in:
parent
f2314e918b
commit
49398698b5
152
Makefile.emscripten
Normal file
152
Makefile.emscripten
Normal file
@ -0,0 +1,152 @@
|
||||
TARGET = retroarch.html
|
||||
|
||||
OBJ = frontend/frontend_emscripten.o \
|
||||
retroarch.o \
|
||||
file.o \
|
||||
file_path.o \
|
||||
driver.o \
|
||||
conf/config_file.o \
|
||||
settings.o \
|
||||
hash.o \
|
||||
dynamic.o \
|
||||
dynamic_dummy.o \
|
||||
message.o \
|
||||
rewind.o \
|
||||
movie.o \
|
||||
gfx/gfx_common.o \
|
||||
input/input_common.o \
|
||||
core_options.o \
|
||||
patch.o \
|
||||
compat/compat.o \
|
||||
screenshot.o \
|
||||
cheats.o \
|
||||
audio/utils.o \
|
||||
input/overlay.o \
|
||||
fifo_buffer.o \
|
||||
gfx/scaler/scaler.o \
|
||||
gfx/scaler/pixconv.o \
|
||||
gfx/scaler/scaler_int.o \
|
||||
gfx/scaler/filter.o \
|
||||
gfx/state_tracker.o \
|
||||
gfx/shader_parse.o \
|
||||
gfx/fonts/fonts.o \
|
||||
gfx/fonts/bitmapfont.o \
|
||||
gfx/image.o \
|
||||
audio/resampler.o \
|
||||
audio/sinc.o \
|
||||
audio/null.o \
|
||||
performance.o
|
||||
|
||||
HAVE_OPENGL = 1
|
||||
HAVE_RGUI = 1
|
||||
HAVE_SDL = 1
|
||||
HAVE_SDL_IMAGE = 1
|
||||
HAVE_FREETYPE = 1
|
||||
HAVE_ZLIB = 1
|
||||
HAVE_FBO = 1
|
||||
|
||||
libretro ?= -lretro
|
||||
|
||||
LIBS = -lm
|
||||
DEFINES = -I. -DHAVE_SCREENSHOTS -DHAVE_NULLAUDIO -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.9.3\"
|
||||
LDFLAGS = -L. -static-libgcc -s TOTAL_MEMORY=268435456 -s FULL_ES2=1
|
||||
|
||||
ifeq ($(SCALER_NO_SIMD), 1)
|
||||
DEFINES += -DSCALER_NO_SIMD
|
||||
endif
|
||||
|
||||
ifeq ($(PERF_TEST), 1)
|
||||
DEFINES += -DPERF_TEST
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_RGUI), 1)
|
||||
DEFINES += -DHAVE_RGUI
|
||||
OBJ += frontend/menu/menu_common.o frontend/menu/rgui.o frontend/menu/history.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL), 1)
|
||||
OBJ += input/sdl_input.o
|
||||
LIBS += -lSDL
|
||||
DEFINES += -ISDL -DHAVE_SDL
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_THREADS), 1)
|
||||
OBJ += autosave.o thread.o gfx/thread_wrapper.o
|
||||
DEFINES += -DHAVE_THREADS
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_OPENGL), 1)
|
||||
OBJ += gfx/gl.o gfx/math/matrix.o gfx/fonts/gl_font.o gfx/fonts/gl_raster_font.o gfx/gfx_context.o gfx/context/emscriptenegl_ctx.o gfx/shader_glsl.o
|
||||
DEFINES += -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_EGL -DHAVE_OVERLAY -DHAVE_GLSL
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_ZLIB), 1)
|
||||
OBJ += gfx/rpng/rpng.o file_extract.o
|
||||
DEFINES += -DHAVE_ZLIB
|
||||
ifeq ($(WANT_MINIZ), 1)
|
||||
OBJ += deps/miniz/miniz.o
|
||||
DEFINES += -DWANT_MINIZ
|
||||
else
|
||||
LIBS += -lz
|
||||
DEFINES += -DHAVE_ZLIB_DEFLATE
|
||||
endif
|
||||
endif
|
||||
|
||||
LIBS += $(libretro)
|
||||
|
||||
ifeq ($(HAVE_FBO), 1)
|
||||
DEFINES += -DHAVE_FBO
|
||||
endif
|
||||
|
||||
ifneq ($(V), 1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
LDFLAGS += -O0 -g -s LABEL_DEBUG=1
|
||||
else
|
||||
LDFLAGS += -O2 -ffast-math
|
||||
endif
|
||||
|
||||
CFLAGS += -Wall -Wno-unused-result -Wno-unused-variable -I. -std=gnu99
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJ)
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
$(Q)$(LD) -o $@ $(OBJ) $(LIBS) $(LDFLAGS)
|
||||
|
||||
%.o: %.c
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
%.o: %.cpp
|
||||
@$(if $(Q), $(shell echo echo CXX $<),)
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f deps/miniz/*.o
|
||||
rm -f frontend/*.o
|
||||
rm -f frontend/menu/*.o
|
||||
rm -f audio/*.o
|
||||
rm -f audio/xaudio-c/*.o
|
||||
rm -f compat/*.o
|
||||
rm -f compat/rxml/*.o
|
||||
rm -f conf/*.o
|
||||
rm -f gfx/scaler/*.o
|
||||
rm -f gfx/*.o
|
||||
rm -f gfx/d3d9/*.o
|
||||
rm -f gfx/context/*.o
|
||||
rm -f gfx/math/*.o
|
||||
rm -f gfx/fonts/*.o
|
||||
rm -f gfx/py_state/*.o
|
||||
rm -f gfx/rpng/*.o
|
||||
rm -f record/*.o
|
||||
rm -f input/*.o
|
||||
rm -f $(TARGET)
|
||||
rm -f retroarch-joyconfig.exe
|
||||
rm -f tools/*.o
|
||||
|
||||
.PHONY: all clean
|
||||
|
@ -128,6 +128,8 @@ enum
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_SL
|
||||
#elif defined(HAVE_DSOUND)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_DSOUND
|
||||
#elif defined(EMSCRIPTEN)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_NULL
|
||||
#elif defined(HAVE_SDL)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_SDL
|
||||
#elif defined(HAVE_XAUDIO)
|
||||
@ -195,6 +197,8 @@ enum
|
||||
#define EXT_EXECUTABLES "xex|XEX"
|
||||
#elif defined(GEKKO)
|
||||
#define EXT_EXECUTABLES "dol|DOL"
|
||||
#else
|
||||
#define EXT_EXECUTABLES "???"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
2
driver.c
2
driver.c
@ -62,7 +62,7 @@ static const audio_driver_t *audio_drivers[] = {
|
||||
#ifdef HAVE_JACK
|
||||
&audio_jack,
|
||||
#endif
|
||||
#ifdef HAVE_SDL
|
||||
#if defined(HAVE_SDL) && !defined(EMSCRIPTEN)
|
||||
&audio_sdl,
|
||||
#endif
|
||||
#ifdef HAVE_XAUDIO
|
||||
|
127
frontend/frontend_emscripten.c
Normal file
127
frontend/frontend_emscripten.c
Normal file
@ -0,0 +1,127 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2013 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2013 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <emscripten/emscripten.h>
|
||||
#include "../general.h"
|
||||
#include "../conf/config_file.h"
|
||||
#include "../file.h"
|
||||
|
||||
#ifdef HAVE_RGUI
|
||||
#include "../frontend/menu/rgui.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_RGUI) || defined(HAVE_RMENU) || defined(HAVE_RMENU_XUI)
|
||||
#define HAVE_MENU
|
||||
#else
|
||||
#undef HAVE_MENU
|
||||
#endif
|
||||
|
||||
static bool menuloop;
|
||||
|
||||
void mainloop(void)
|
||||
{
|
||||
if (g_extern.system.shutdown)
|
||||
{
|
||||
RARCH_ERR("Exit...\n");
|
||||
emscripten_cancel_main_loop();
|
||||
}
|
||||
else if (menuloop)
|
||||
{
|
||||
if (!menu_iterate())
|
||||
{
|
||||
menuloop = false;
|
||||
driver_set_nonblock_state(driver.nonblock_state);
|
||||
|
||||
if (driver.audio_data && !audio_start_func())
|
||||
{
|
||||
RARCH_ERR("Failed to resume audio driver. Will continue without audio.\n");
|
||||
g_extern.audio_active = false;
|
||||
}
|
||||
|
||||
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU);
|
||||
}
|
||||
}
|
||||
else if (g_extern.lifecycle_mode_state & (1ULL << MODE_LOAD_GAME))
|
||||
{
|
||||
load_menu_game_prepare();
|
||||
|
||||
// If ROM load fails, we exit RetroArch. On console it might make more sense to go back to menu though ...
|
||||
if (load_menu_game())
|
||||
g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME);
|
||||
else
|
||||
{
|
||||
#ifdef RARCH_CONSOLE
|
||||
g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_LOAD_GAME);
|
||||
}
|
||||
else if (g_extern.lifecycle_mode_state & (1ULL << MODE_GAME))
|
||||
{
|
||||
bool r;
|
||||
if (g_extern.is_paused && !g_extern.is_oneshot)
|
||||
r = rarch_main_idle_iterate();
|
||||
else
|
||||
r = rarch_main_iterate();
|
||||
if (!r)
|
||||
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME);
|
||||
}
|
||||
else if (g_extern.lifecycle_mode_state & (1ULL << MODE_MENU))
|
||||
{
|
||||
g_extern.lifecycle_mode_state |= 1ULL << MODE_MENU_PREINIT;
|
||||
// Menu should always run with vsync on.
|
||||
video_set_nonblock_state_func(false);
|
||||
|
||||
if (driver.audio_data)
|
||||
audio_stop_func();
|
||||
|
||||
menuloop = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_extern.system.shutdown = true;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
emscripten_set_canvas_size(800, 600);
|
||||
|
||||
rarch_main_clear_state();
|
||||
rarch_init_msg_queue();
|
||||
|
||||
char *_argv[] = { "retroarch", "--menu", "-v" };
|
||||
|
||||
int init_ret;
|
||||
if ((init_ret = rarch_main_init(3, _argv))) return init_ret;
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
menu_init();
|
||||
g_extern.lifecycle_mode_state |= 1ULL << MODE_GAME;
|
||||
|
||||
// If we started a ROM directly from command line,
|
||||
// push it to ROM history.
|
||||
if (!g_extern.libretro_dummy)
|
||||
menu_rom_history_push_current();
|
||||
#endif
|
||||
|
||||
emscripten_set_main_loop(mainloop, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
268
gfx/context/emscriptenegl_ctx.c
Normal file
268
gfx/context/emscriptenegl_ctx.c
Normal file
@ -0,0 +1,268 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2013 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2012 - Michael Lelli
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// VideoCore context, for Rasperry Pi.
|
||||
|
||||
#include "../../driver.h"
|
||||
#include "../gfx_context.h"
|
||||
#include "../gl_common.h"
|
||||
#include "../gfx_common.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES/gl.h>
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
static EGLContext g_egl_ctx;
|
||||
static EGLSurface g_egl_surf;
|
||||
static EGLDisplay g_egl_dpy;
|
||||
static EGLConfig g_config;
|
||||
static bool g_quit;
|
||||
|
||||
static bool g_inited;
|
||||
|
||||
static unsigned g_fb_width;
|
||||
static unsigned g_fb_height;
|
||||
|
||||
static void gfx_ctx_swap_interval(unsigned interval)
|
||||
{
|
||||
// no way to control vsync in WebGL
|
||||
(void)interval;
|
||||
}
|
||||
|
||||
static void gfx_ctx_check_window(bool *quit,
|
||||
bool *resize, unsigned *width, unsigned *height, unsigned frame_count)
|
||||
{
|
||||
(void)frame_count;
|
||||
(void)width;
|
||||
(void)height;
|
||||
|
||||
*resize = false;
|
||||
*quit = g_quit;
|
||||
}
|
||||
|
||||
static void gfx_ctx_swap_buffers(void)
|
||||
{
|
||||
eglSwapBuffers(g_egl_dpy, g_egl_surf);
|
||||
}
|
||||
|
||||
static void gfx_ctx_set_resize(unsigned width, unsigned height)
|
||||
{
|
||||
(void)width;
|
||||
(void)height;
|
||||
}
|
||||
|
||||
static void gfx_ctx_update_window_title(void)
|
||||
{
|
||||
char buf[128];
|
||||
gfx_get_fps(buf, sizeof(buf), false);
|
||||
}
|
||||
|
||||
static void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
|
||||
{
|
||||
*width = g_fb_width;
|
||||
*height = g_fb_height;
|
||||
}
|
||||
|
||||
static void gfx_ctx_destroy(void);
|
||||
|
||||
static bool gfx_ctx_init(void)
|
||||
{
|
||||
EGLint width;
|
||||
EGLint height;
|
||||
|
||||
RARCH_LOG("[VC/EMSCRIPTEN]: Initializing...\n");
|
||||
if (g_inited)
|
||||
{
|
||||
RARCH_ERR("[VC/EMSCRIPTEN]: Attempted to re-initialize driver.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
EGLint num_config;
|
||||
|
||||
static const EGLint attribute_list[] =
|
||||
{
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_ALPHA_SIZE, 8,
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
static const EGLint context_attributes[] =
|
||||
{
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
// get an EGL display connection
|
||||
g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if (!g_egl_dpy)
|
||||
goto error;
|
||||
|
||||
// initialize the EGL display connection
|
||||
if (!eglInitialize(g_egl_dpy, NULL, NULL))
|
||||
goto error;
|
||||
|
||||
// get an appropriate EGL frame buffer configuration
|
||||
if (!eglChooseConfig(g_egl_dpy, attribute_list, &g_config, 1, &num_config))
|
||||
goto error;
|
||||
|
||||
// create an EGL rendering context
|
||||
g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, EGL_NO_CONTEXT, context_attributes);
|
||||
if (!g_egl_ctx)
|
||||
goto error;
|
||||
|
||||
// create an EGL window surface
|
||||
g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, 0, NULL);
|
||||
if (!g_egl_surf)
|
||||
goto error;
|
||||
|
||||
// connect the context to the surface
|
||||
if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx))
|
||||
goto error;
|
||||
|
||||
eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_WIDTH, &width);
|
||||
eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_HEIGHT, &height);
|
||||
g_fb_width = width;
|
||||
g_fb_height = height;
|
||||
RARCH_LOG("[VC/EMSCRIPTEN]: Dimensions: %ux%u\n", width, height);
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
gfx_ctx_destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_set_video_mode(
|
||||
unsigned width, unsigned height,
|
||||
bool fullscreen)
|
||||
{
|
||||
if (g_inited)
|
||||
return false;
|
||||
|
||||
g_inited = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_bind_api(enum gfx_ctx_api api)
|
||||
{
|
||||
switch (api)
|
||||
{
|
||||
case GFX_CTX_OPENGL_ES_API:
|
||||
return eglBindAPI(EGL_OPENGL_ES_API);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_ctx_destroy(void)
|
||||
{
|
||||
if (g_egl_dpy)
|
||||
{
|
||||
if (g_egl_ctx)
|
||||
{
|
||||
eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
eglDestroyContext(g_egl_dpy, g_egl_ctx);
|
||||
}
|
||||
|
||||
if (g_egl_surf)
|
||||
{
|
||||
eglDestroySurface(g_egl_dpy, g_egl_surf);
|
||||
}
|
||||
|
||||
eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
eglTerminate(g_egl_dpy);
|
||||
}
|
||||
|
||||
g_egl_ctx = NULL;
|
||||
g_egl_surf = NULL;
|
||||
g_egl_dpy = NULL;
|
||||
g_config = 0;
|
||||
g_inited = false;
|
||||
}
|
||||
|
||||
static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
|
||||
{
|
||||
*input = NULL;
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||
return;
|
||||
|
||||
void *sdlinput = input_sdl.init();
|
||||
|
||||
if (sdlinput)
|
||||
{
|
||||
*input = &input_sdl;
|
||||
*input_data = sdlinput;
|
||||
}
|
||||
}
|
||||
|
||||
static bool gfx_ctx_has_focus(void)
|
||||
{
|
||||
return g_inited;
|
||||
}
|
||||
|
||||
static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
|
||||
{
|
||||
return SDL_GL_GetProcAddress(symbol);
|
||||
}
|
||||
|
||||
static float gfx_ctx_translate_aspect(unsigned width, unsigned height)
|
||||
{
|
||||
return (float)width / height;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_write_egl_image(const void *frame, unsigned width, unsigned height, unsigned pitch, bool rgb32, unsigned index, void **image_handle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const gfx_ctx_driver_t gfx_ctx_emscripten = {
|
||||
gfx_ctx_init,
|
||||
gfx_ctx_destroy,
|
||||
gfx_ctx_bind_api,
|
||||
gfx_ctx_swap_interval,
|
||||
gfx_ctx_set_video_mode,
|
||||
gfx_ctx_get_video_size,
|
||||
gfx_ctx_translate_aspect,
|
||||
gfx_ctx_update_window_title,
|
||||
gfx_ctx_check_window,
|
||||
gfx_ctx_set_resize,
|
||||
gfx_ctx_has_focus,
|
||||
gfx_ctx_swap_buffers,
|
||||
gfx_ctx_input_driver,
|
||||
gfx_ctx_get_proc_address,
|
||||
gfx_ctx_init_egl_image_buffer,
|
||||
gfx_ctx_write_egl_image,
|
||||
NULL,
|
||||
"emscripten",
|
||||
};
|
@ -13,6 +13,7 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../general.h"
|
||||
#include "gfx_context.h"
|
||||
#include <string.h>
|
||||
|
||||
@ -51,14 +52,17 @@ static const gfx_ctx_driver_t *gfx_ctx_drivers[] = {
|
||||
#if defined(IOS) || defined(OSX) //< Don't use __APPLE__ as it breaks basic SDL builds
|
||||
&gfx_ctx_apple,
|
||||
#endif
|
||||
#if defined(HAVE_SDL) && defined(HAVE_OPENGL)
|
||||
#if defined(HAVE_SDL) && defined(HAVE_OPENGL) && !defined(EMSCRIPTEN)
|
||||
&gfx_ctx_sdl_gl,
|
||||
#endif
|
||||
#ifdef EMSCRIPTEN
|
||||
&gfx_ctx_emscripten,
|
||||
#endif
|
||||
};
|
||||
|
||||
const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(gfx_ctx_drivers) / sizeof(gfx_ctx_drivers[0]); i++)
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(gfx_ctx_drivers); i++)
|
||||
{
|
||||
if (strcmp(gfx_ctx_drivers[i]->ident, ident) == 0)
|
||||
return gfx_ctx_drivers[i];
|
||||
@ -69,7 +73,7 @@ const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident)
|
||||
|
||||
const gfx_ctx_driver_t *gfx_ctx_init_first(enum gfx_ctx_api api)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(gfx_ctx_drivers) / sizeof(gfx_ctx_drivers[0]); i++)
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(gfx_ctx_drivers); i++)
|
||||
{
|
||||
if (gfx_ctx_drivers[i]->bind_api(api))
|
||||
{
|
||||
|
@ -108,6 +108,7 @@ extern const gfx_ctx_driver_t gfx_ctx_wgl;
|
||||
extern const gfx_ctx_driver_t gfx_ctx_videocore;
|
||||
extern const gfx_ctx_driver_t gfx_ctx_bbqnx;
|
||||
extern const gfx_ctx_driver_t gfx_ctx_apple;
|
||||
extern const gfx_ctx_driver_t gfx_ctx_emscripten;
|
||||
extern const gfx_ctx_driver_t gfx_ctx_null;
|
||||
|
||||
const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident); // Finds driver with ident. Does not initialize.
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "input_common.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "../general.h"
|
||||
#include "../driver.h"
|
||||
@ -47,7 +48,7 @@ static const rarch_joypad_driver_t *joypad_drivers[] = {
|
||||
#if defined(__linux) && !defined(ANDROID)
|
||||
&linuxraw_joypad,
|
||||
#endif
|
||||
#ifdef HAVE_SDL
|
||||
#if defined(HAVE_SDL) && !defined(EMSCRIPTEN)
|
||||
&sdl_joypad,
|
||||
#endif
|
||||
#endif
|
||||
|
@ -24,6 +24,10 @@
|
||||
#include "../libretro.h"
|
||||
#include "input_common.h"
|
||||
|
||||
#if !(SDL_MAJOR_VERSION <= 1 && SDL_MINOR_VERSION <= 2)
|
||||
#define SDL_GetKeyState SDL_GetKeyboardState
|
||||
#endif
|
||||
|
||||
typedef struct sdl_input
|
||||
{
|
||||
const rarch_joypad_driver_t *joypad;
|
||||
@ -51,9 +55,8 @@ static bool sdl_key_pressed(int key)
|
||||
|
||||
int sym = input_translate_rk_to_keysym((enum retro_key)key);
|
||||
|
||||
int num_keys;
|
||||
int num_keys = 0xFFFF;
|
||||
Uint8 *keymap = SDL_GetKeyState(&num_keys);
|
||||
if (sym < 0 || sym >= num_keys)
|
||||
return false;
|
||||
|
||||
return keymap[sym];
|
||||
@ -216,16 +219,24 @@ static void sdl_input_free(void *data)
|
||||
|
||||
static void sdl_poll_mouse(sdl_input_t *sdl)
|
||||
{
|
||||
(void)sdl;
|
||||
#ifndef EMSCRIPTEN
|
||||
Uint8 btn = SDL_GetRelativeMouseState(&sdl->mouse_x, &sdl->mouse_y);
|
||||
SDL_GetMouseState(&sdl->mouse_abs_x, &sdl->mouse_abs_y);
|
||||
sdl->mouse_l = SDL_BUTTON(SDL_BUTTON_LEFT) & btn ? 1 : 0;
|
||||
sdl->mouse_r = SDL_BUTTON(SDL_BUTTON_RIGHT) & btn ? 1 : 0;
|
||||
sdl->mouse_m = SDL_BUTTON(SDL_BUTTON_MIDDLE) & btn ? 1 : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void sdl_input_poll(void *data)
|
||||
{
|
||||
#ifdef EMSCRIPTEN
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event));
|
||||
#else
|
||||
SDL_PumpEvents();
|
||||
#endif
|
||||
sdl_input_t *sdl = (sdl_input_t*)data;
|
||||
|
||||
input_joypad_poll(sdl->joypad);
|
||||
|
@ -58,6 +58,10 @@
|
||||
#include <mach/mach.h>
|
||||
#endif
|
||||
|
||||
#ifdef EMSCRIPTEN
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
#ifdef PERF_TEST
|
||||
#define MAX_COUNTERS 64
|
||||
static struct rarch_perf_counter *perf_counters[MAX_COUNTERS];
|
||||
@ -145,6 +149,8 @@ rarch_time_t rarch_get_time_usec(void)
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &tv) < 0)
|
||||
return 0;
|
||||
return tv.tv_sec * INT64_C(1000000) + (tv.tv_nsec + 500) / 1000;
|
||||
#elif defined(EMSCRIPTEN)
|
||||
return emscripten_get_now() * 1000;
|
||||
#else
|
||||
#error "Your platform does not have a timer function implemented in rarch_get_time_usec(). Cannot continue."
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user