diff --git a/desmume/src/frontend/interface/draw_sdl_window.cpp b/desmume/src/frontend/interface/draw_sdl_window.cpp
new file mode 100755
index 000000000..dc9760054
--- /dev/null
+++ b/desmume/src/frontend/interface/draw_sdl_window.cpp
@@ -0,0 +1,344 @@
+/*
+ Copyright (C) 2006 yopyop
+ Copyright (C) 2006-2007 shash
+ Copyright (C) 2008-2020 DeSmuME team
+
+ This file 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 Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ This file 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 the this software. If not, see .
+*/
+
+// This entire file is basically a copy of the Posix CLI rendering / input processing.
+
+#include "interface.h"
+#include "../../NDSSystem.h"
+#include "../../GPU.h"
+#include "../posix/shared/ctrlssdl.h"
+
+#ifdef INCLUDE_OPENGL_2D
+ #include
+ #include
+ #include
+#endif
+
+// SDL drawing & input processing
+static SDL_Surface *surface;
+static int sdl_videoFlags;
+struct ctrls_event_config ctrls_cfg;
+static float nds_screen_size_ratio = 1.0f;
+bool opengl_2d = true;
+#ifdef INCLUDE_OPENGL_2D
+GLuint sdl_ogl_screen_texture[2];
+#endif
+// TODO: Make configurable instead.
+const u16 cli_kb_cfg[NB_KEYS] =
+ {
+ SDLK_x, // A
+ SDLK_z, // B
+ SDLK_RSHIFT, // select
+ SDLK_RETURN, // start
+ SDLK_RIGHT, // Right
+ SDLK_LEFT, // Left
+ SDLK_UP, // Up
+ SDLK_DOWN, // Down
+ SDLK_w, // R
+ SDLK_q, // L
+ SDLK_s, // X
+ SDLK_a, // Y
+ SDLK_p, // DEBUG
+ SDLK_o, // BOOST
+ SDLK_BACKSPACE, // Lid
+ };
+
+#ifdef INCLUDE_OPENGL_2D
+static void resizeWindow_stub(u16 width, u16 height, GLuint *sdl_ogl_screen_texture) {}
+#else
+static void resizeWindow_stub(u16 width, u16 height, void *sdl_ogl_screen_texture) {}
+#endif
+
+static void sdl_draw_no_opengl()
+{
+#ifdef HAVE_LIBAGG
+ //TODO : osd->update();
+ //TODO : DrawHUD();
+#endif
+ const NDSDisplayInfo &displayInfo = GPU->GetDisplayInfo();
+ const size_t pixCount = GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT;
+ ColorspaceApplyIntensityToBuffer16((u16 *)displayInfo.masterNativeBuffer, pixCount, displayInfo.backlightIntensity[NDSDisplayID_Main]);
+ ColorspaceApplyIntensityToBuffer16((u16 *)displayInfo.masterNativeBuffer + pixCount, pixCount, displayInfo.backlightIntensity[NDSDisplayID_Touch]);
+
+ SDL_Surface *rawImage = SDL_CreateRGBSurfaceFrom(displayInfo.masterNativeBuffer, GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2, 16, GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16), 0x001F, 0x03E0, 0x7C00, 0);
+ if(rawImage == NULL) return;
+
+ SDL_BlitSurface(rawImage, 0, surface, 0);
+ SDL_UpdateRect(surface, 0, 0, 0, 0);
+ SDL_FreeSurface(rawImage);
+#ifdef HAVE_LIBAGG
+ //TODO : osd->clear();
+#endif
+}
+
+#ifdef INCLUDE_OPENGL_2D
+static void sdl_draw_with_opengl(GLuint *screen_texture)
+{
+ desmume_draw_opengl(sdl_ogl_screen_texture);
+ /* Flush the drawing to the screen */
+ SDL_GL_SwapBuffers();
+}
+
+/* initialization openGL function */
+static int initGL(GLuint *screen_texture) {
+ GLenum errCode;
+ u16 blank_texture[256 * 256];
+
+ memset(blank_texture, 0, sizeof(blank_texture));
+
+ /* Enable Texture Mapping */
+ glEnable( GL_TEXTURE_2D );
+
+ /* Set the background black */
+ glClearColor( 0.0f, 0.0f, 0.0f, 0.5f );
+
+ /* Depth buffer setup */
+ glClearDepth( 1.0f );
+
+ /* Enables Depth Testing */
+ glEnable( GL_DEPTH_TEST );
+
+ /* The Type Of Depth Test To Do */
+ glDepthFunc( GL_LEQUAL );
+
+ /* Create The Texture */
+ glGenTextures(2, screen_texture);
+
+ for (int i = 0; i < 2; i++)
+ {
+ glBindTexture(GL_TEXTURE_2D, screen_texture[i]);
+
+ /* Generate The Texture */
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256,
+ 0, GL_RGBA,
+ GL_UNSIGNED_SHORT_1_5_5_5_REV,
+ blank_texture);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ /* Linear Filtering */
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+
+ if ((errCode = glGetError()) != GL_NO_ERROR) {
+ const GLubyte *errString;
+
+ errString = gluErrorString(errCode);
+ fprintf( stderr, "Failed to init GL: %s\n", errString);
+
+ return 0;
+ }
+
+ return 1;
+}
+
+static void resizeWindow(u16 width, u16 height, GLuint *screen_texture) {
+ int comp_width = 3 * width;
+ int comp_height = 2 * height;
+ GLenum errCode;
+
+ surface = SDL_SetVideoMode(width, height, 32, sdl_videoFlags);
+ initGL(screen_texture);
+
+#ifdef HAVE_LIBAGG
+ //Hud.reset();
+#endif
+
+ if ( comp_width > comp_height) {
+ width = 2*height/3;
+ }
+ height = 3*width/2;
+ nds_screen_size_ratio = 256.0 / (double)width;
+
+ /* Setup our viewport. */
+ glViewport( 0, 0, ( GLint )width, ( GLint )height );
+
+ /*
+ * change to the projection matrix and set
+ * our viewing volume.
+ */
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity( );
+
+ gluOrtho2D( 0.0, 256.0, 384.0, 0.0);
+
+ /* Make sure we're chaning the model view and not the projection */
+ glMatrixMode( GL_MODELVIEW );
+
+ /* Reset The View */
+ glLoadIdentity( );
+
+ if ((errCode = glGetError()) != GL_NO_ERROR) {
+ const GLubyte *errString;
+
+ errString = gluErrorString(errCode);
+ fprintf( stderr, "GL resize failed: %s\n", errString);
+ }
+}
+#endif
+
+
+//
+//
+
+
+EXPORTED int desmume_draw_window_init(BOOL auto_pause, BOOL use_opengl_if_possible)
+{
+ opengl_2d = use_opengl_if_possible;
+
+ // SDL_Init is called in desmume_init.
+
+ SDL_WM_SetCaption("Desmume SDL", NULL);
+
+ const SDL_VideoInfo *videoInfo;
+ videoInfo = SDL_GetVideoInfo();
+ if (!videoInfo) {
+ fprintf(stderr, "Video query failed: %s\n", SDL_GetError());
+ return -1;
+ }
+
+ if ( videoInfo->blit_hw ) {
+ sdl_videoFlags |= SDL_HWACCEL;
+ }
+
+#ifdef INCLUDE_OPENGL_2D
+ if (opengl_2d) {
+ /* the flags to pass to SDL_SetVideoMode */
+ sdl_videoFlags = SDL_OPENGL; /* Enable OpenGL in SDL */
+ sdl_videoFlags |= SDL_HWPALETTE; /* Store the palette in hardware */
+ sdl_videoFlags |= SDL_RESIZABLE; /* Enable window resizing */
+
+
+ /* This checks to see if surfaces can be stored in memory */
+ if ( videoInfo->hw_available )
+ sdl_videoFlags |= SDL_HWSURFACE;
+ else
+ sdl_videoFlags |= SDL_SWSURFACE;
+
+
+ /* Sets up OpenGL double buffering */
+ SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+
+ surface = SDL_SetVideoMode( 256, 192 * 2, 32,
+ sdl_videoFlags );
+
+ /* Verify there is a surface */
+ if (!surface) {
+ fprintf(stderr, "Video mode set failed: %s\n", SDL_GetError( ));
+ return -1;
+ }
+
+
+ /* initialize OpenGL */
+ if (!initGL(sdl_ogl_screen_texture)) {
+ fprintf(stderr, "Failed to init GL, fall back to software render\n");
+
+ opengl_2d = 0;
+ }
+ }
+
+ if (!opengl_2d) {
+#endif
+ sdl_videoFlags |= SDL_SWSURFACE;
+ surface = SDL_SetVideoMode(256, 384, 32, sdl_videoFlags);
+
+ if (!surface) {
+ fprintf( stderr, "Video mode set failed: %s\n", SDL_GetError( ) );
+ return -1;
+ }
+#ifdef INCLUDE_OPENGL_2D
+ }
+
+ /* set the initial window size */
+ if (opengl_2d) {
+ resizeWindow( 256, 192*2, sdl_ogl_screen_texture);
+ }
+#endif
+
+ // TODO: Make configurable instead.
+ load_default_config(cli_kb_cfg);
+
+ ctrls_cfg.boost = 0;
+ ctrls_cfg.sdl_quit = 0;
+ ctrls_cfg.auto_pause = auto_pause;
+ ctrls_cfg.focused = 1;
+ ctrls_cfg.fake_mic = 0;
+ ctrls_cfg.keypad = 0;
+#ifdef INCLUDE_OPENGL_2D
+ ctrls_cfg.screen_texture = sdl_ogl_screen_texture;
+#else
+ ctrls_cfg.screen_texture = NULL;
+#endif
+ ctrls_cfg.resize_cb = &resizeWindow_stub;
+
+ return 0;
+}
+
+EXPORTED void desmume_draw_window_input()
+{
+ SDL_Event event;
+
+ ctrls_cfg.nds_screen_size_ratio = nds_screen_size_ratio;
+
+ /* Look for queued events and update keypad status */
+ /* IMPORTANT: Reenable joystick events if needed. */
+ if(SDL_JoystickEventState(SDL_QUERY) == SDL_IGNORE)
+ SDL_JoystickEventState(SDL_ENABLE);
+
+ /* There's an event waiting to be processed? */
+ while ( !ctrls_cfg.sdl_quit &&
+ (SDL_PollEvent(&event) || (!ctrls_cfg.focused && SDL_WaitEvent(&event))))
+ {
+ process_ctrls_event( event, &ctrls_cfg);
+ }
+
+ /* Update mouse position and click */
+ if(mouse.down) NDS_setTouchPos(mouse.x, mouse.y);
+ if(mouse.click)
+ {
+ NDS_releaseTouch();
+ mouse.click = FALSE;
+ }
+
+ update_keypad(ctrls_cfg.keypad); /* Update keypad */
+}
+
+EXPORTED void desmume_draw_window_frame()
+{
+#ifdef INCLUDE_OPENGL_2D
+ if (opengl_2d) {
+ sdl_draw_with_opengl(sdl_ogl_screen_texture);
+ ctrls_cfg.resize_cb = &resizeWindow;
+ }
+ else
+#endif
+ sdl_draw_no_opengl();
+}
+
+EXPORTED BOOL desmume_draw_window_has_quit()
+{
+ return ctrls_cfg.sdl_quit;
+}
+
+EXPORTED void desmume_draw_window_free()
+{
+ SDL_Quit();
+}
\ No newline at end of file
diff --git a/desmume/src/frontend/interface/interface.cpp b/desmume/src/frontend/interface/interface.cpp
new file mode 100644
index 000000000..3aef3712a
--- /dev/null
+++ b/desmume/src/frontend/interface/interface.cpp
@@ -0,0 +1,402 @@
+/*
+ Copyright (C) 2006 yopyop
+ Copyright (C) 2006-2007 shash
+ Copyright (C) 2008-2020 DeSmuME team
+
+ This file 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 Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ This file 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 the this software. If not, see .
+*/
+
+#include "interface.h"
+
+#include
+#include "../../NDSSystem.h"
+#include "../../GPU.h"
+// TODO: OSD Support isn't really done yet! Test!
+#include "../modules/osd/agg/agg_osd.h"
+#include "../../SPU.h"
+#include "../../rasterize.h"
+#include "../../saves.h"
+#include "../../mc.h"
+#include "../../firmware.h"
+#include "../posix/shared/sndsdl.h"
+#include "../posix/shared/ctrlssdl.h"
+
+#define SCREENS_PIXEL_SIZE 98304
+volatile bool execute = false;
+
+
+SoundInterface_struct *SNDCoreList[] = {
+ &SNDDummy,
+ &SNDDummy,
+ &SNDSDL,
+ NULL
+};
+
+GPU3DInterface *core3DList[] = {
+ &gpu3DNull,
+ &gpu3DRasterize,
+ NULL
+};
+
+EXPORTED int desmume_init()
+{
+ NDS_Init();
+ // TODO: Option to disable audio
+ SPU_ChangeSoundCore(SNDCORE_SDL, 735 * 4);
+ SPU_SetSynchMode(0, 0);
+ SPU_SetVolume(100);
+ SNDSDLSetAudioVolume(100);
+ // TODO: Option to configure 3d
+ GPU->Change3DRendererByID(RENDERID_SOFTRASTERIZER);
+ // TODO: Without SDL init?
+ if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1) {
+ fprintf(stderr, "Error trying to initialize SDL: %s\n",
+ SDL_GetError());
+ return -1;
+ }
+ execute = false;
+ return 0;
+}
+
+EXPORTED void desmume_free()
+{
+ execute = false;
+ NDS_DeInit();
+ SDL_Quit();
+}
+
+EXPORTED void desmume_set_language(u8 lang)
+{
+ CommonSettings.fwConfig.language = lang;
+}
+
+EXPORTED int desmume_open(const char *filename)
+{
+ int i;
+ clear_savestates();
+ i = NDS_LoadROM(filename);
+ return i;
+}
+
+EXPORTED void desmume_set_savetype(int type) {
+ backup_setManualBackupType(type);
+}
+
+
+EXPORTED void desmume_pause()
+{
+ execute = false;
+ SPU_Pause(1);
+}
+
+EXPORTED void desmume_resume()
+{
+ execute = true;
+ SPU_Pause(0);
+}
+
+EXPORTED void desmume_reset()
+{
+ NDS_Reset();
+ desmume_resume();
+}
+
+EXPORTED BOOL desmume_running()
+{
+ return execute;
+}
+
+EXPORTED void desmume_skip_next_frame()
+{
+ NDS_SkipNextFrame();
+}
+
+EXPORTED void desmume_cycle()
+{
+ u16 keypad;
+ /* Joystick events */
+ /* Retrieve old value: can use joysticks w/ another device (from our side) */
+ keypad = get_keypad();
+ /* Process joystick events if any */
+ process_joystick_events(&keypad);
+ /* Update keypad value */
+ update_keypad(keypad);
+
+ NDS_exec();
+ SPU_Emulate_user();
+}
+
+EXPORTED int desmume_sdl_get_ticks()
+{
+ return SDL_GetTicks();
+}
+
+#ifdef INCLUDE_OPENGL_2D
+EXPORTED void desmume_draw_opengl(GLuint *texture)
+{
+#ifdef HAVE_LIBAGG
+ //TODO : osd->update();
+ //TODO : DrawHUD();
+#endif
+ const NDSDisplayInfo &displayInfo = GPU->GetDisplayInfo();
+
+ /* Clear The Screen And The Depth Buffer */
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ /* Move Into The Screen 5 Units */
+ glLoadIdentity();
+
+ /* Draw the main screen as a textured quad */
+ glBindTexture(GL_TEXTURE_2D, texture[NDSDisplayID_Main]);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT,
+ GL_RGBA,
+ GL_UNSIGNED_SHORT_1_5_5_5_REV,
+ displayInfo.renderedBuffer[NDSDisplayID_Main]);
+
+ GLfloat backlightIntensity = displayInfo.backlightIntensity[NDSDisplayID_Main];
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.00f, 0.00f); glVertex2f( 0.0f, 0.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
+ glTexCoord2f(1.00f, 0.00f); glVertex2f(256.0f, 0.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
+ glTexCoord2f(1.00f, 0.75f); glVertex2f(256.0f, 192.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
+ glTexCoord2f(0.00f, 0.75f); glVertex2f( 0.0f, 192.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
+ glEnd();
+
+ /* Draw the touch screen as a textured quad */
+ glBindTexture(GL_TEXTURE_2D, texture[NDSDisplayID_Touch]);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT,
+ GL_RGBA,
+ GL_UNSIGNED_SHORT_1_5_5_5_REV,
+ displayInfo.renderedBuffer[NDSDisplayID_Touch]);
+
+ backlightIntensity = displayInfo.backlightIntensity[NDSDisplayID_Touch];
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.00f, 0.00f); glVertex2f( 0.0f, 192.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
+ glTexCoord2f(1.00f, 0.00f); glVertex2f(256.0f, 192.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
+ glTexCoord2f(1.00f, 0.75f); glVertex2f(256.0f, 384.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
+ glTexCoord2f(0.00f, 0.75f); glVertex2f( 0.0f, 384.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
+ glEnd();
+#ifdef HAVE_LIBAGG
+ //TODO : osd->clear();
+#endif
+}
+EXPORTED extern BOOL desmume_has_opengl()
+{
+ return true;
+}
+#else
+EXPORTED extern BOOL desmume_has_opengl()
+{
+ return false;
+}
+#endif
+
+// SDL drawing is in draw_sdl_window.cpp
+
+EXPORTED u16 *desmume_draw_raw()
+{
+ const NDSDisplayInfo &displayInfo = GPU->GetDisplayInfo();
+ const size_t pixCount = GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT;
+ ColorspaceApplyIntensityToBuffer16((u16 *)displayInfo.masterNativeBuffer, pixCount, displayInfo.backlightIntensity[NDSDisplayID_Main]);
+ ColorspaceApplyIntensityToBuffer16((u16 *)displayInfo.masterNativeBuffer + pixCount, pixCount, displayInfo.backlightIntensity[NDSDisplayID_Touch]);
+
+ return (u16*) displayInfo.masterNativeBuffer;
+}
+
+EXPORTED void desmume_draw_raw_as_rgbx(u8 *buffer) {
+ u16 *gpuFramebuffer = desmume_draw_raw();
+
+ for (int i = 0; i < SCREENS_PIXEL_SIZE; i++) {
+ buffer[(i * 4) + 2] = ((gpuFramebuffer[i] >> 0) & 0x1f) << 3;
+ buffer[(i * 4) + 1] = ((gpuFramebuffer[i] >> 5) & 0x1f) << 3;
+ buffer[(i * 4) + 0] = ((gpuFramebuffer[i] >> 10) & 0x1f) << 3;
+ }
+}
+
+//EXPORTED int desmume_sram_load(const char *file_name);
+//EXPORTED int desmume_sram_save(const char *file_name);
+//
+EXPORTED void desmume_savestate_clear()
+{
+ clear_savestates();
+}
+
+//EXPORTED BOOL desmume_savestate_load(const char *file_name);
+//EXPORTED BOOL desmume_savestate_save(const char *file_name);
+
+EXPORTED void desmume_savestate_scan()
+{
+ scan_savestates();
+}
+
+EXPORTED void desmume_savestate_slot_load(int index)
+{
+ loadstate_slot(index);
+}
+
+EXPORTED void desmume_savestate_slot_save(int index)
+{
+ savestate_slot(index);
+}
+
+EXPORTED BOOL desmume_savestate_slot_exists(int index)
+{
+ return savestates[index].exists;
+}
+
+EXPORTED char* desmume_savestate_slot_date(int index)
+{
+ return savestates[index].date;
+}
+
+EXPORTED BOOL desmume_gpu_get_layer_main_enable_state(int layer_index)
+{
+ return GPU->GetEngineMain()->GetLayerEnableState(layer_index);
+}
+
+EXPORTED BOOL desmume_gpu_get_layer_sub_enable_state(int layer_index)
+{
+ return GPU->GetEngineSub()->GetLayerEnableState(layer_index);
+}
+
+EXPORTED void desmume_gpu_set_layer_main_enable_state(int layer_index, BOOL the_state)
+{
+ GPU->GetEngineMain()->SetLayerEnableState(layer_index, the_state);
+}
+
+EXPORTED void desmume_gpu_set_layer_sub_enable_state(int layer_index, BOOL the_state)
+{
+ GPU->GetEngineSub()->SetLayerEnableState(layer_index, the_state);
+}
+
+EXPORTED int desmume_volume_get()
+{
+ return SNDSDLGetAudioVolume();
+}
+EXPORTED void desmume_volume_set(int volume)
+{
+ SNDSDLSetAudioVolume(volume);
+}
+
+//
+//EXPORTED unsigned char desmume_memory_read_byte(int address);
+//EXPORTED signed char desmume_memory_read_byte_signed(int address);
+//EXPORTED unsigned short desmume_memory_read_short(int address);
+//EXPORTED signed short desmume_memory_read_short_signed(int address);
+//EXPORTED unsigned long desmume_memory_read_long(int address);
+//EXPORTED signed long desmume_memory_read_long_signed(int address);
+//EXPORTED unsigned char *desmume_memory_read_byterange(int address, int length);
+//
+//EXPORTED void desmume_memory_write_byte(int address, unsigned char value);
+//EXPORTED void desmume_memory_write_byte_signed(int address, signed char value);
+//EXPORTED void desmume_memory_write_short(int address, unsigned short value);
+//EXPORTED void desmume_memory_write_short_signed(int address, signed short value);
+//EXPORTED void desmume_memory_write_long(int address, unsigned long value);
+//EXPORTED void desmume_memory_write_long_signed(int address, signed long value);
+//EXPORTED void desmume_memory_write_byterange(int address, const unsigned char *bytes);
+//
+//EXPORTED long desmume_memory_read_register(char* register_name);
+//EXPORTED void desmume_memory_write_register(char* register_name, long value);
+//
+//EXPORTED void desmume_memory_register_write(int address, int size, memory_cb_fnc cb);
+//EXPORTED void desmume_memory_register_read(int address, int size, memory_cb_fnc cb);
+//EXPORTED void desmume_memory_register_exec(int address, int size, memory_cb_fnc cb);
+
+EXPORTED void desmume_screenshot(char *screenshot_buffer)
+{
+ u16 *gpuFramebuffer = (u16 *)GPU->GetDisplayInfo().masterNativeBuffer;
+ static int seq = 0;
+
+ for (int i = 0; i < SCREENS_PIXEL_SIZE; i++) {
+ screenshot_buffer[(i * 3) + 0] = ((gpuFramebuffer[i] >> 0) & 0x1f) << 3;
+ screenshot_buffer[(i * 3) + 1] = ((gpuFramebuffer[i] >> 5) & 0x1f) << 3;
+ screenshot_buffer[(i * 3) + 2] = ((gpuFramebuffer[i] >> 10) & 0x1f) << 3;
+ }
+
+}
+
+EXPORTED BOOL desmume_input_joy_init(void)
+{
+ return (BOOL) init_joy();
+}
+
+EXPORTED void desmume_input_joy_uninit(void)
+{
+ return uninit_joy();
+}
+
+EXPORTED u16 desmume_input_joy_number_connected(void)
+{
+ return nbr_joy;
+}
+
+EXPORTED u16 desmume_input_joy_get_key(int index)
+{
+ return get_joy_key(index);
+}
+
+EXPORTED u16 desmume_input_joy_get_set_key(int index)
+{
+ return get_set_joy_key(index);
+}
+
+EXPORTED void desmume_input_joy_set_key(int index, int joystick_key_index)
+{
+ joypad_cfg[index] = joystick_key_index;
+}
+
+EXPORTED void desmume_input_keypad_update(u16 keys)
+{
+ update_keypad(keys);
+}
+
+EXPORTED u16 desmume_input_keypad_get(void)
+{
+ return get_keypad();
+}
+
+EXPORTED void desmume_input_set_touch_pos(u16 x, u16 y)
+{
+ NDS_setTouchPos(x, y);
+}
+
+EXPORTED void desmume_input_release_touch()
+{
+ NDS_releaseTouch();
+}
+
+//EXPORTED BOOL desmume_movie_is_active();
+//EXPORTED BOOL desmume_movie_is_recording();
+//EXPORTED BOOL desmume_movie_is_playing();
+//EXPORTED char *desmume_movie_get_mode();
+//EXPORTED int desmume_movie_get_length();
+//EXPORTED char *desmume_movie_get_name();
+//EXPORTED int desmume_movie_get_rerecord_count();
+//EXPORTED void desmume_movie_set_rerecord_count(int count);
+//EXPORTED BOOL desmume_movie_get_rerecord_counting();
+//EXPORTED void desmume_movie_set_rerecord_counting(BOOL state);
+//EXPORTED BOOL desmume_movie_get_readonly();
+//EXPORTED void desmume_movie_set_readonly(BOOL state);
+//EXPORTED void desmume_movie_play(/* ??? */);
+//EXPORTED void desmume_movie_replay();
+//EXPORTED void desmume_movie_stop();
+//
+//EXPORTED void desmume_gui_pixel(int x, int y, int color);
+//EXPORTED void desmume_gui_line(int x1, int y1, int x2, int y2, int color);
+//EXPORTED void desmume_gui_box(int x1, int y1, int x2, int y2, int fillcolor, int outlinecolor);
+//EXPORTED void desmume_gui_box(int x1, int y1, int x2, int y2, int fillcolor, int outlinecolor);
+//EXPORTED void desmume_gui_text(int x, int y, char *str, int textcolor, BOOL has_backcolor, int backcolor);
+//EXPORTED void desmume_gui_gdoverlay(int dx, int dy, char* str, int alphamul);
+//EXPORTED void desmume_gui_opacity(int alpha);
\ No newline at end of file
diff --git a/desmume/src/frontend/interface/interface.h b/desmume/src/frontend/interface/interface.h
new file mode 100755
index 000000000..2165c198a
--- /dev/null
+++ b/desmume/src/frontend/interface/interface.h
@@ -0,0 +1,169 @@
+/*
+ Copyright (C) 2006 yopyop
+ Copyright (C) 2006-2007 shash
+ Copyright (C) 2008-2020 DeSmuME team
+
+ This file 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 Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ This file 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 the this software. If not, see .
+*/
+
+#ifndef DESMUME_INTERFACE_H
+#define DESMUME_INTERFACE_H
+
+#include
+#include <../../types.h>
+
+#ifdef HAVE_GL_GL_H
+#define INCLUDE_OPENGL_2D
+#endif
+
+#ifdef INCLUDE_OPENGL_2D
+#include
+#include
+#endif
+
+// Define EXPORTED for any platform
+#ifdef _WIN32
+# ifdef WIN_EXPORT
+# define EXPORTED __declspec( dllexport )
+# else
+# define EXPORTED __declspec( dllimport )
+# endif
+#else
+# define EXPORTED
+#endif
+
+extern "C" {
+// callback for memory hooks: if it returns false, remove it.
+typedef BOOL (*memory_cb_fnc)(void);
+
+EXPORTED int desmume_init(void);
+EXPORTED void desmume_free(void);
+
+// 0 = Japanese, 1 = English, 2 = French, 3 = German, 4 = Italian, 5 = Spanish
+EXPORTED void desmume_set_language(u8 language);
+EXPORTED int desmume_open(const char *filename);
+EXPORTED void desmume_set_savetype(int type);
+EXPORTED void desmume_pause(void);
+EXPORTED void desmume_resume(void);
+EXPORTED void desmume_reset(void);
+EXPORTED BOOL desmume_running(void);
+EXPORTED void desmume_skip_next_frame(void);
+EXPORTED void desmume_cycle(void);
+
+EXPORTED int desmume_sdl_get_ticks();
+
+// Drawing is either supported manually via a custom OpenGL texture...
+#ifdef INCLUDE_OPENGL_2D
+EXPORTED void desmume_draw_opengl(GLuint *texture);
+#endif
+EXPORTED BOOL desmume_has_opengl();
+// ... or via an SDL window created by Desmume.
+EXPORTED int desmume_draw_window_init(BOOL auto_pause, BOOL use_opengl_if_possible);
+EXPORTED void desmume_draw_window_input();
+EXPORTED void desmume_draw_window_frame();
+EXPORTED BOOL desmume_draw_window_has_quit();
+EXPORTED void desmume_draw_window_free();
+// ... or have fun working with the display buffer directly
+EXPORTED u16 *desmume_draw_raw();
+EXPORTED void desmume_draw_raw_as_rgbx(u8 *buffer);
+
+EXPORTED int desmume_sram_load(const char *file_name);
+EXPORTED int desmume_sram_save(const char *file_name);
+
+EXPORTED void desmume_savestate_clear();
+EXPORTED BOOL desmume_savestate_load(const char *file_name);
+EXPORTED BOOL desmume_savestate_save(const char *file_name);
+EXPORTED void desmume_savestate_scan();
+EXPORTED void desmume_savestate_slot_load(int index);
+EXPORTED void desmume_savestate_slot_save(int index);
+EXPORTED BOOL desmume_savestate_slot_exists(int index);
+EXPORTED char* desmume_savestate_slot_date(int index);
+
+EXPORTED void desmume_savestate_load_slot(int num);
+EXPORTED void desmume_savestate_save_slot(int num);
+
+EXPORTED BOOL desmume_gpu_get_layer_main_enable_state(int layer_index);
+EXPORTED BOOL desmume_gpu_get_layer_sub_enable_state(int layer_index);
+EXPORTED void desmume_gpu_set_layer_main_enable_state(int layer_index, BOOL the_state);
+EXPORTED void desmume_gpu_set_layer_sub_enable_state(int layer_index, BOOL the_state);
+
+EXPORTED int desmume_volume_get();
+EXPORTED void desmume_volume_set(int volume);
+
+EXPORTED unsigned char desmume_memory_read_byte(int address);
+EXPORTED signed char desmume_memory_read_byte_signed(int address);
+EXPORTED unsigned short desmume_memory_read_short(int address);
+EXPORTED signed short desmume_memory_read_short_signed(int address);
+EXPORTED unsigned long desmume_memory_read_long(int address);
+EXPORTED signed long desmume_memory_read_long_signed(int address);
+EXPORTED unsigned char *desmume_memory_read_byterange(int address, int length);
+
+EXPORTED void desmume_memory_write_byte(int address, unsigned char value);
+EXPORTED void desmume_memory_write_byte_signed(int address, signed char value);
+EXPORTED void desmume_memory_write_short(int address, unsigned short value);
+EXPORTED void desmume_memory_write_short_signed(int address, signed short value);
+EXPORTED void desmume_memory_write_long(int address, unsigned long value);
+EXPORTED void desmume_memory_write_long_signed(int address, signed long value);
+EXPORTED void desmume_memory_write_byterange(int address, const unsigned char *bytes);
+
+EXPORTED long desmume_memory_read_register(char* register_name);
+EXPORTED void desmume_memory_write_register(char* register_name, long value);
+
+EXPORTED void desmume_memory_register_write(int address, int size, memory_cb_fnc cb);
+EXPORTED void desmume_memory_register_read(int address, int size, memory_cb_fnc cb);
+EXPORTED void desmume_memory_register_exec(int address, int size, memory_cb_fnc cb);
+
+// Buffer must have the size 98304*3
+EXPORTED void desmume_screenshot(char *screenshot_buffer);
+
+// For automatic input processing with the SDL window, see desmume_draw_sdl_input.
+EXPORTED BOOL desmume_input_joy_init(void);
+EXPORTED void desmume_input_joy_uninit(void);
+EXPORTED u16 desmume_input_joy_number_connected(void);
+EXPORTED u16 desmume_input_joy_get_key(int index);
+EXPORTED u16 desmume_input_joy_get_set_key(int index);
+EXPORTED void desmume_input_joy_set_key(int index, int joystick_key_index);
+
+EXPORTED void desmume_input_keypad_update(u16 keys);
+EXPORTED u16 desmume_input_keypad_get(void);
+
+EXPORTED void desmume_input_set_touch_pos(u16 x, u16 y);
+EXPORTED void desmume_input_release_touch();
+
+EXPORTED BOOL desmume_movie_is_active();
+EXPORTED BOOL desmume_movie_is_recording();
+EXPORTED BOOL desmume_movie_is_playing();
+EXPORTED char *desmume_movie_get_mode();
+EXPORTED int desmume_movie_get_length();
+EXPORTED char *desmume_movie_get_name();
+EXPORTED int desmume_movie_get_rerecord_count();
+EXPORTED void desmume_movie_set_rerecord_count(int count);
+EXPORTED BOOL desmume_movie_get_rerecord_counting();
+EXPORTED void desmume_movie_set_rerecord_counting(BOOL state);
+EXPORTED BOOL desmume_movie_get_readonly();
+EXPORTED void desmume_movie_set_readonly(BOOL state);
+EXPORTED void desmume_movie_play(/* ??? */);
+EXPORTED void desmume_movie_replay();
+EXPORTED void desmume_movie_stop();
+
+EXPORTED void desmume_gui_pixel(int x, int y, int color);
+EXPORTED void desmume_gui_line(int x1, int y1, int x2, int y2, int color);
+EXPORTED void desmume_gui_box(int x1, int y1, int x2, int y2, int fillcolor, int outlinecolor);
+EXPORTED void desmume_gui_box(int x1, int y1, int x2, int y2, int fillcolor, int outlinecolor);
+EXPORTED void desmume_gui_text(int x, int y, char *str, int textcolor, BOOL has_backcolor, int backcolor);
+EXPORTED void desmume_gui_gdoverlay(int dx, int dy, char* str, int alphamul);
+EXPORTED void desmume_gui_opacity(int alpha);
+
+};
+#endif //DESMUME_INTERFACE_H