android: native egl surface
fps counter using imgui restart emulator with new game in same process
This commit is contained in:
parent
b15b8de12b
commit
4c1acfeab1
|
@ -344,8 +344,10 @@ static void rend_create_renderer()
|
|||
#endif
|
||||
}
|
||||
|
||||
static void rend_init_renderer()
|
||||
void rend_init_renderer()
|
||||
{
|
||||
if (renderer == NULL)
|
||||
rend_create_renderer();
|
||||
if (!renderer->Init())
|
||||
{
|
||||
delete renderer;
|
||||
|
@ -360,7 +362,7 @@ static void rend_init_renderer()
|
|||
}
|
||||
}
|
||||
|
||||
static void rend_term_renderer()
|
||||
void rend_term_renderer()
|
||||
{
|
||||
renderer->Term();
|
||||
delete renderer;
|
||||
|
@ -371,6 +373,7 @@ static void rend_term_renderer()
|
|||
fallback_renderer = NULL;
|
||||
}
|
||||
killtex();
|
||||
gui_term();
|
||||
}
|
||||
|
||||
void* rend_thread(void* p)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "hw/pvr/Renderer_if.h"
|
||||
#include "hw/pvr/spg.h"
|
||||
#include "hw/aica/dsp.h"
|
||||
#include "imgread/common.h"
|
||||
|
||||
void FlushCache();
|
||||
void LoadCustom();
|
||||
|
@ -94,7 +95,7 @@ int64_t get_time_usec(void)
|
|||
}
|
||||
|
||||
|
||||
int GetFile(char *szFileName, char *szParse=0, u32 flags=0)
|
||||
int GetFile(char *szFileName, char *szParse /* = 0 */, u32 flags /* = 0 */)
|
||||
{
|
||||
cfgLoadStr("config","image",szFileName,"null");
|
||||
if (strcmp(szFileName,"null")==0)
|
||||
|
@ -305,11 +306,27 @@ void dc_reset()
|
|||
sh4_cpu.Reset(false);
|
||||
}
|
||||
|
||||
static bool init_done;
|
||||
|
||||
int dc_init(int argc,wchar* argv[])
|
||||
{
|
||||
setbuf(stdin,0);
|
||||
setbuf(stdout,0);
|
||||
setbuf(stderr,0);
|
||||
if (init_done)
|
||||
{
|
||||
if(ParseCommandLine(argc,argv))
|
||||
{
|
||||
return 69;
|
||||
}
|
||||
InitSettings();
|
||||
LoadSettings(false);
|
||||
if (DiscSwap())
|
||||
LoadCustom();
|
||||
dc_reset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (!_vmem_reserve())
|
||||
{
|
||||
printf("Failed to alloc mem\n");
|
||||
|
@ -394,6 +411,7 @@ int dc_init(int argc,wchar* argv[])
|
|||
#elif DC_PLATFORM == DC_PLATFORM_ATOMISWAVE
|
||||
mcfg_CreateAtomisWaveControllers();
|
||||
#endif
|
||||
init_done = true;
|
||||
|
||||
dc_reset();
|
||||
|
||||
|
|
|
@ -956,6 +956,7 @@ struct gl4rend : Renderer
|
|||
CollectCleanup();
|
||||
|
||||
gl_term();
|
||||
gl_free_osd_resources();
|
||||
}
|
||||
|
||||
bool Process(TA_context* ctx) { return ProcessFrame(ctx); }
|
||||
|
|
|
@ -29,6 +29,9 @@ int fbdev = -1;
|
|||
#define GL_MAJOR_VERSION 0x821B
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _ANDROID
|
||||
#include <android/native_window.h> // requires ndk r5 or newer
|
||||
#endif
|
||||
|
||||
/*
|
||||
GL|ES 2
|
||||
|
@ -407,7 +410,6 @@ GLuint fogTextureId;
|
|||
// Create a basic GLES context
|
||||
bool gl_init(void* wind, void* disp)
|
||||
{
|
||||
#if !defined(_ANDROID)
|
||||
gl.setup.native_wind=(EGLNativeWindowType)wind;
|
||||
gl.setup.native_disp=(EGLNativeDisplayType)disp;
|
||||
|
||||
|
@ -431,17 +433,43 @@ GLuint fogTextureId;
|
|||
|
||||
if (gl.setup.surface == 0)
|
||||
{
|
||||
EGLint pi32ConfigAttribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT , EGL_DEPTH_SIZE, 24, EGL_STENCIL_SIZE, 8, EGL_NONE };
|
||||
EGLint pi32ConfigAttribs[] = {
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_DEPTH_SIZE, 24,
|
||||
EGL_STENCIL_SIZE, 8,
|
||||
EGL_NONE
|
||||
};
|
||||
EGLint pi32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2 , EGL_NONE };
|
||||
|
||||
int num_config;
|
||||
|
||||
EGLConfig config;
|
||||
if (!eglChooseConfig(gl.setup.display, pi32ConfigAttribs, &config, 1, &num_config) || (num_config != 1))
|
||||
{
|
||||
// Fall back to non preserved swap buffers
|
||||
EGLint pi32ConfigFallbackAttribs[] = {
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_DEPTH_SIZE, 24,
|
||||
EGL_STENCIL_SIZE, 8,
|
||||
EGL_NONE
|
||||
};
|
||||
if (!eglChooseConfig(gl.setup.display, pi32ConfigFallbackAttribs, &config, 1, &num_config) || (num_config != 1))
|
||||
{
|
||||
printf("EGL Error: eglChooseConfig failed\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#ifdef _ANDROID
|
||||
EGLint format;
|
||||
if (!eglGetConfigAttrib(gl.setup.display, config, EGL_NATIVE_VISUAL_ID, &format))
|
||||
{
|
||||
printf("eglGetConfigAttrib() returned error %d", eglGetError());
|
||||
return false;
|
||||
}
|
||||
ANativeWindow_setBuffersGeometry((ANativeWindow *)wind, 0, 0, format);
|
||||
#endif
|
||||
|
||||
gl.setup.surface = eglCreateWindowSurface(gl.setup.display, config, (EGLNativeWindowType)wind, NULL);
|
||||
|
||||
|
@ -460,7 +488,6 @@ GLuint fogTextureId;
|
|||
if (eglCheck())
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
eglMakeCurrent(gl.setup.display, gl.setup.surface, gl.setup.surface, gl.setup.context);
|
||||
|
||||
|
@ -485,13 +512,6 @@ GLuint fogTextureId;
|
|||
return true;
|
||||
}
|
||||
|
||||
void egl_stealcntx()
|
||||
{
|
||||
gl.setup.context=eglGetCurrentContext();
|
||||
gl.setup.display=eglGetCurrentDisplay();
|
||||
gl.setup.surface=eglGetCurrentSurface(EGL_DRAW);
|
||||
}
|
||||
|
||||
//swap buffers
|
||||
void gl_swap()
|
||||
{
|
||||
|
@ -508,24 +528,37 @@ GLuint fogTextureId;
|
|||
//destroy the gles context and free resources
|
||||
void gl_term()
|
||||
{
|
||||
glDeleteProgram(gl.modvol_shader.program);
|
||||
glDeleteBuffers(1, &gl.vbo.geometry);
|
||||
gl.vbo.geometry = 0;
|
||||
glDeleteBuffers(1, &gl.vbo.modvols);
|
||||
glDeleteBuffers(1, &gl.vbo.idxs);
|
||||
glDeleteBuffers(1, &gl.vbo.idxs2);
|
||||
glcache.DeleteTextures(1, &fbTextureId);
|
||||
fbTextureId = 0;
|
||||
gl_free_osd_resources();
|
||||
|
||||
memset(gl.pogram_table, 0, sizeof(gl.pogram_table));
|
||||
|
||||
#if HOST_OS==OS_WINDOWS
|
||||
ReleaseDC((HWND)gl.setup.native_wind,(HDC)gl.setup.native_disp);
|
||||
#endif
|
||||
#ifdef TARGET_PANDORA
|
||||
#if defined(TARGET_PANDORA) || defined(_ANDROID)
|
||||
eglMakeCurrent(gl.setup.display, NULL, NULL, EGL_NO_CONTEXT);
|
||||
if (gl.setup.context)
|
||||
if (gl.setup.context != NULL)
|
||||
eglDestroyContext(gl.setup.display, gl.setup.context);
|
||||
if (gl.setup.surface)
|
||||
if (gl.setup.surface != NULL)
|
||||
eglDestroySurface(gl.setup.display, gl.setup.surface);
|
||||
#ifdef TARGET_PANDORA
|
||||
if (gl.setup.display)
|
||||
eglTerminate(gl.setup.display);
|
||||
if (fbdev>=0)
|
||||
close( fbdev );
|
||||
|
||||
fbdev=-1;
|
||||
gl.setup.context=0;
|
||||
gl.setup.surface=0;
|
||||
gl.setup.display=0;
|
||||
#endif
|
||||
gl.setup.context = NULL;
|
||||
gl.setup.surface = NULL;
|
||||
gl.setup.display = NULL;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
|
@ -956,7 +989,6 @@ bool CompilePipelineShader( PipelineShader* s)
|
|||
}
|
||||
|
||||
GLuint osd_tex;
|
||||
GLuint osd_font;
|
||||
|
||||
void gl_load_osd_resources()
|
||||
{
|
||||
|
@ -964,18 +996,15 @@ void gl_load_osd_resources()
|
|||
int w, h;
|
||||
if (osd_tex == 0)
|
||||
osd_tex = loadPNG(get_readonly_data_path("/data/buttons.png"), w, h);
|
||||
if (osd_font == 0)
|
||||
{
|
||||
#ifdef TARGET_PANDORA
|
||||
osd_font = loadPNG(get_readonly_data_path("/font2.png"), w, h);
|
||||
#else
|
||||
osd_font = loadPNG(get_readonly_data_path("/pixmaps/font.png"), w, h);
|
||||
if (osd_font == 0)
|
||||
osd_font = loadPNG(get_readonly_data_path("/font.png"), w, h);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void gl_free_osd_resources()
|
||||
{
|
||||
if (osd_tex != 0) {
|
||||
glcache.DeleteTextures(1, &osd_tex);
|
||||
osd_tex = 0;
|
||||
}
|
||||
}
|
||||
bool gl_create_resources()
|
||||
{
|
||||
if (gl.vbo.geometry != 0)
|
||||
|
@ -1289,112 +1318,6 @@ static void ClearBG()
|
|||
|
||||
void DrawButton2(float* xy, bool state) { DrawButton(xy,state?0:255); }
|
||||
|
||||
static void DrawCenteredText(float yy, float scale, int transparency, const char* text)
|
||||
// Draw a centered text. Font is loaded from font2.png file. Each char is 16*16 size, so scale it down so it's not too big
|
||||
// Transparency 255=opaque, 0=not visible
|
||||
{
|
||||
Vertex vtx;
|
||||
|
||||
vtx.z=1;
|
||||
|
||||
float w=float(strlen(text)*14)*scale;
|
||||
|
||||
float x=320-w/2.0f;
|
||||
float y=yy;
|
||||
float h=16.0f*scale;
|
||||
w=14.0f*scale;
|
||||
float step=32.0f/512.0f;
|
||||
float step2=4.0f/512.0f;
|
||||
|
||||
if (transparency<0) transparency=0;
|
||||
if (transparency>255) transparency=255;
|
||||
|
||||
for (int i=0; i<strlen(text); i++) {
|
||||
int c=text[i];
|
||||
float u=float(c%16);
|
||||
float v=float(c/16);
|
||||
|
||||
vtx.col[0]=vtx.col[1]=vtx.col[2]=255;
|
||||
vtx.col[3]=transparency;
|
||||
|
||||
vtx.x=x; vtx.y=y;
|
||||
vtx.u=u*step+step2; vtx.v=v*step+step2;
|
||||
*pvrrc.verts.Append()=vtx;
|
||||
|
||||
vtx.x=x+w; vtx.y=y;
|
||||
vtx.u=u*step+step-step2; vtx.v=v*step+step2;
|
||||
*pvrrc.verts.Append()=vtx;
|
||||
|
||||
vtx.x=x; vtx.y=y+h;
|
||||
vtx.u=u*step+step2; vtx.v=v*step+step-step2;
|
||||
*pvrrc.verts.Append()=vtx;
|
||||
|
||||
vtx.x=x+w; vtx.y=y+h;
|
||||
vtx.u=u*step+step-step2; vtx.v=v*step+step-step2;
|
||||
*pvrrc.verts.Append()=vtx;
|
||||
|
||||
x+=w;
|
||||
|
||||
osd_count+=4;
|
||||
}
|
||||
}
|
||||
static void DrawRightedText(float yy, float scale, int transparency, const char* text)
|
||||
// Draw a text right justified. Font is loaded from font.png file. Each char is 16*16 size, so scale it down so it's not too big
|
||||
// Transparency 255=opaque, 0=not visible
|
||||
{
|
||||
Vertex vtx;
|
||||
|
||||
vtx.z=1;
|
||||
|
||||
float w = float(strlen(text) * 14) * scale * scale_x;
|
||||
|
||||
float x = scale_x / 2 * (640 + screen_width * 480 / screen_height) - w;
|
||||
float y = yy * scale_y;
|
||||
float h = 16.0f * scale * scale_y;
|
||||
w = 14.0f * scale * scale_x;
|
||||
float step=32.0f/512.0f;
|
||||
float step2=4.0f/512.0f;
|
||||
|
||||
if (transparency<0) transparency=0;
|
||||
if (transparency>255) transparency=255;
|
||||
|
||||
for (int i=0; i<strlen(text); i++) {
|
||||
int c=text[i];
|
||||
float u=float(c%16);
|
||||
float v=float(c/16);
|
||||
|
||||
vtx.col[0]=vtx.col[1]=vtx.col[2]=255;
|
||||
vtx.col[3]=transparency;
|
||||
|
||||
vtx.x=x; vtx.y=y;
|
||||
vtx.u=u*step+step2; vtx.v=v*step+step2;
|
||||
*pvrrc.verts.Append()=vtx;
|
||||
|
||||
vtx.x=x+w; vtx.y=y;
|
||||
vtx.u=u*step+step-step2; vtx.v=v*step+step2;
|
||||
*pvrrc.verts.Append()=vtx;
|
||||
|
||||
vtx.x=x; vtx.y=y+h;
|
||||
vtx.u=u*step+step2; vtx.v=v*step+step-step2;
|
||||
*pvrrc.verts.Append()=vtx;
|
||||
|
||||
vtx.x=x+w; vtx.y=y+h;
|
||||
vtx.u=u*step+step-step2; vtx.v=v*step+step-step2;
|
||||
*pvrrc.verts.Append()=vtx;
|
||||
|
||||
x+=w;
|
||||
|
||||
osd_count+=4;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TARGET_PANDORA
|
||||
char OSD_Info[128];
|
||||
int OSD_Delay=0;
|
||||
char OSD_Counters[256];
|
||||
int OSD_Counter=0;
|
||||
#endif
|
||||
|
||||
static float LastFPSTime;
|
||||
static int lastFrameCount = 0;
|
||||
static float fps = -1;
|
||||
|
@ -1427,28 +1350,6 @@ void OSD_HOOK()
|
|||
DrawButton2(vjoy_pos[12],0);
|
||||
}
|
||||
#endif
|
||||
#ifdef TARGET_PANDORA
|
||||
if (OSD_Delay) {
|
||||
DrawCenteredText(400, 1.0f, (OSD_Delay<255)?OSD_Delay:255, OSD_Info);
|
||||
OSD_Delay--; //*TODO* Delay should be in ms, not in ticks...
|
||||
}
|
||||
if (OSD_Counter) {
|
||||
DrawRightedText(20, 1.0f, 255, OSD_Counters);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (settings.rend.ShowFPS && osd_font) {
|
||||
if (os_GetSeconds() - LastFPSTime > 0.5) {
|
||||
fps = (FrameCount - lastFrameCount) / (os_GetSeconds() - LastFPSTime);
|
||||
LastFPSTime = os_GetSeconds();
|
||||
lastFrameCount = FrameCount;
|
||||
}
|
||||
if (fps >= 0) {
|
||||
char text[32];
|
||||
sprintf(text, "F:%.1f", fps);
|
||||
DrawRightedText(460, 1.f, 196, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define OSD_TEX_W 512
|
||||
|
@ -1518,40 +1419,19 @@ void OSD_DRAW(GLuint shader_program)
|
|||
glDrawArrays(GL_TRIANGLE_STRIP,osd_base+i*4,4);
|
||||
}
|
||||
#endif
|
||||
if (osd_font)
|
||||
if (settings.rend.ShowFPS)
|
||||
{
|
||||
float u=0;
|
||||
float v=0;
|
||||
|
||||
verify(glIsProgram(shader_program));
|
||||
|
||||
float dc_width=640;
|
||||
float dc_height=480;
|
||||
|
||||
float dc2s_scale_h=screen_height/480.0f;
|
||||
float ds2s_offs_x=(screen_width-dc2s_scale_h*640)/2;
|
||||
|
||||
|
||||
glcache.BindTexture(GL_TEXTURE_2D,osd_font);
|
||||
glcache.UseProgram(shader_program);
|
||||
|
||||
glcache.Enable(GL_BLEND);
|
||||
glcache.Disable(GL_DEPTH_TEST);
|
||||
glcache.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
||||
glcache.DepthMask(false);
|
||||
glcache.DepthFunc(GL_ALWAYS);
|
||||
|
||||
|
||||
glcache.Disable(GL_CULL_FACE);
|
||||
glcache.Disable(GL_SCISSOR_TEST);
|
||||
|
||||
|
||||
int dfa=osd_count/4;
|
||||
|
||||
for (int i=0;i<dfa;i++)
|
||||
glDrawArrays(GL_TRIANGLE_STRIP,osd_base+i*4,4);
|
||||
double now = os_GetSeconds();
|
||||
if (now - LastFPSTime >= 1.0) {
|
||||
fps = (FrameCount - lastFrameCount) / (now - LastFPSTime);
|
||||
LastFPSTime = now;
|
||||
lastFrameCount = FrameCount;
|
||||
}
|
||||
if (fps >= 0) {
|
||||
char text[32];
|
||||
sprintf(text, "F:%.1f", fps);
|
||||
gui_display_fps(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2033,6 +1913,7 @@ struct glesrend : Renderer
|
|||
{
|
||||
if (KillTex)
|
||||
killtex();
|
||||
gl_term();
|
||||
}
|
||||
|
||||
bool Process(TA_context* ctx) { return ProcessFrame(ctx); }
|
||||
|
|
|
@ -142,6 +142,7 @@ enum ModifierVolumeMode { Xor, Or, Inclusion, Exclusion, ModeCount };
|
|||
|
||||
bool gl_init(void* wind, void* disp);
|
||||
void gl_load_osd_resources();
|
||||
void gl_free_osd_resources();
|
||||
void gl_swap();
|
||||
bool ProcessFrame(TA_context* ctx);
|
||||
void UpdateFogTexture(u8 *fog_table, GLenum texture_slot, GLint fog_image_format);
|
||||
|
|
|
@ -312,6 +312,7 @@ static void gui_display_commands()
|
|||
if (ImGui::Button("Exit", ImVec2(150 * scaling, 50 * scaling)))
|
||||
{
|
||||
dc_resume_emu(false);
|
||||
gui_state = ClosedNoResume;
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
@ -445,10 +446,12 @@ static void detect_input_popup(int index, bool analog)
|
|||
|
||||
static void controller_mapping_popup(GamepadDevice *gamepad)
|
||||
{
|
||||
ImGui::SetNextWindowPos(ImVec2(0, 0));
|
||||
ImGui::SetNextWindowSize(ImVec2(screen_width, screen_height));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0);
|
||||
if (ImGui::BeginPopupModal("Controller Mapping", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove))
|
||||
{
|
||||
const float width = 350 * scaling;
|
||||
const float height = 450 * scaling;
|
||||
const float width = screen_width / 2;
|
||||
const float col0_width = ImGui::CalcTextSize("Right DPad Downxxx").x + ImGui::GetStyle().FramePadding.x * 2.0f + ImGui::GetStyle().ItemSpacing.x;
|
||||
const float col1_width = width
|
||||
- ImGui::GetStyle().GrabMinSize
|
||||
|
@ -466,7 +469,7 @@ static void controller_mapping_popup(GamepadDevice *gamepad)
|
|||
ImGui::BeginGroup();
|
||||
ImGui::Text(" Buttons ");
|
||||
|
||||
ImGui::BeginChildFrame(ImGui::GetID("buttons"), ImVec2(width, height), ImGuiWindowFlags_None);
|
||||
ImGui::BeginChildFrame(ImGui::GetID("buttons"), ImVec2(width, 0), ImGuiWindowFlags_None);
|
||||
ImGui::Columns(3, "bindings", false);
|
||||
ImGui::SetColumnWidth(0, col0_width);
|
||||
ImGui::SetColumnWidth(1, col1_width);
|
||||
|
@ -499,7 +502,7 @@ static void controller_mapping_popup(GamepadDevice *gamepad)
|
|||
|
||||
ImGui::BeginGroup();
|
||||
ImGui::Text(" Analog Axes ");
|
||||
ImGui::BeginChildFrame(ImGui::GetID("analog"), ImVec2(width, height), ImGuiWindowFlags_None);
|
||||
ImGui::BeginChildFrame(ImGui::GetID("analog"), ImVec2(width, 0), ImGuiWindowFlags_None);
|
||||
ImGui::Columns(3, "bindings", false);
|
||||
ImGui::SetColumnWidth(0, col0_width);
|
||||
ImGui::SetColumnWidth(1, col1_width);
|
||||
|
@ -530,6 +533,7 @@ static void controller_mapping_popup(GamepadDevice *gamepad)
|
|||
ImGui::EndGroup();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
static void gui_display_settings()
|
||||
{
|
||||
|
@ -915,3 +919,28 @@ void gui_display_ui()
|
|||
else if (gui_state == ClosedNoResume)
|
||||
gui_state = Closed;
|
||||
}
|
||||
|
||||
void gui_display_fps(const char *string)
|
||||
{
|
||||
ImGui_Impl_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
ImGui::SetNextWindowBgAlpha(0);
|
||||
ImGui::SetNextWindowPos(ImVec2(0, screen_height), ImGuiCond_Always, ImVec2(0.f, 1.f)); // Lower left corner
|
||||
|
||||
ImGui::Begin("##fps", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoNav
|
||||
| ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoBackground);
|
||||
ImGui::SetWindowFontScale(2);
|
||||
ImGui::TextColored(ImVec4(1, 1, 0, 0.7), string);
|
||||
ImGui::End();
|
||||
|
||||
ImGui::Render();
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
void gui_term()
|
||||
{
|
||||
inited = false;
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
void gui_init();
|
||||
void gui_open_settings();
|
||||
bool gui_is_open();
|
||||
bool gui_display_ui();
|
||||
void gui_display_ui();
|
||||
void gui_display_fps(const char *string);
|
||||
void gui_term();
|
||||
|
||||
extern int screen_dpi;
|
||||
|
|
|
@ -64,6 +64,12 @@
|
|||
android:screenOrientation="sensorLandscape"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.reicast.emulator.NativeGLActivity"
|
||||
android:configChanges="orientation|navigation|screenSize|screenLayout|uiMode|keyboard|keyboardHidden"
|
||||
android:screenOrientation="sensorLandscape"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.dropbox.client2.android.AuthActivity"
|
||||
android:configChanges="orientation|keyboard"
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package com.reicast.emulator;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.SurfaceHolder;
|
||||
|
||||
import com.reicast.emulator.config.EditVJoyActivity;
|
||||
import com.reicast.emulator.emu.JNIdc;
|
||||
import com.reicast.emulator.emu.NativeGLView;
|
||||
|
||||
public class BaseNativeGLActivity extends Activity implements SurfaceHolder.Callback {
|
||||
protected boolean editVjoyMode;
|
||||
protected NativeGLView mView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
String fileName = null;
|
||||
if (getIntent().getAction().equals("com.reicast.EMULATOR"))
|
||||
fileName = Uri.decode(getIntent().getData().toString());
|
||||
|
||||
// Create the actual GL view
|
||||
try {
|
||||
mView = new NativeGLView(this, fileName, editVjoyMode);
|
||||
setContentView(mView);
|
||||
mView.getHolder().addCallback(this);
|
||||
} catch (NativeGLView.EmulatorInitFailed e) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
JNIdc.pause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
JNIdc.resume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mView != null) {
|
||||
mView.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
||||
JNIdc.rendinit(holder.getSurface(), w, h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
JNIdc.rendinit(null, 0, 0);
|
||||
}
|
||||
}
|
|
@ -52,6 +52,7 @@ public class MainActivity extends AppCompatActivity implements
|
|||
|
||||
private SharedPreferences mPrefs;
|
||||
private boolean hasAndroidMarket = false;
|
||||
private boolean activity_paused = false;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -118,7 +119,7 @@ public class MainActivity extends AppCompatActivity implements
|
|||
if (!getFilesDir().exists()) {
|
||||
getFilesDir().mkdir();
|
||||
}
|
||||
JNIdc.initEnvironment(getApplicationContext());
|
||||
JNIdc.initEnvironment((Emulator)getApplicationContext());
|
||||
|
||||
// When viewing a resource, pass its URI to the native code for opening
|
||||
Intent intent = getIntent();
|
||||
|
@ -224,6 +225,9 @@ public class MainActivity extends AppCompatActivity implements
|
|||
}
|
||||
|
||||
public void onEditorSelected(Uri uri) {
|
||||
if (activity_paused)
|
||||
return;
|
||||
activity_paused = true;
|
||||
String home_directory = mPrefs.getString(Config.pref_home,
|
||||
Environment.getExternalStorageDirectory().getAbsolutePath());
|
||||
|
||||
|
@ -234,6 +238,9 @@ public class MainActivity extends AppCompatActivity implements
|
|||
}
|
||||
|
||||
public void onGameSelected(Uri uri) {
|
||||
if (activity_paused)
|
||||
return;
|
||||
activity_paused = true;
|
||||
String home_directory = mPrefs.getString(Config.pref_home,
|
||||
Environment.getExternalStorageDirectory().getAbsolutePath());
|
||||
|
||||
|
@ -245,7 +252,7 @@ public class MainActivity extends AppCompatActivity implements
|
|||
}
|
||||
|
||||
Intent intent = new Intent("com.reicast.EMULATOR",
|
||||
uri, getApplicationContext(), GL2JNIActivity.class);
|
||||
uri, getApplicationContext(), NativeGLActivity.class);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
startActivity(intent);
|
||||
|
@ -369,6 +376,8 @@ public class MainActivity extends AppCompatActivity implements
|
|||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
activity_paused = false;
|
||||
|
||||
CloudFragment cloudfragment = (CloudFragment) getSupportFragmentManager()
|
||||
.findFragmentByTag("CLOUD_FRAG");
|
||||
if (cloudfragment != null && cloudfragment.isVisible()) {
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
package com.reicast.emulator;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.Window;
|
||||
|
||||
import com.reicast.emulator.emu.JNIdc;
|
||||
import com.reicast.emulator.emu.NativeGLView;
|
||||
import com.reicast.emulator.periph.InputDeviceManager;
|
||||
import com.reicast.emulator.periph.SipEmulator;
|
||||
|
||||
import tv.ouya.console.api.OuyaController;
|
||||
|
||||
public class NativeGLActivity extends BaseNativeGLActivity implements ActivityCompat.OnRequestPermissionsResultCallback {
|
||||
public static byte[] syms;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
InputDeviceManager.getInstance().startListening(getApplicationContext());
|
||||
|
||||
Emulator app = (Emulator)getApplicationContext();
|
||||
app.getConfigurationPrefs(prefs);
|
||||
|
||||
OuyaController.init(this);
|
||||
JNIdc.initControllers(Emulator.maple_devices, Emulator.maple_expansion_devices);
|
||||
|
||||
app.loadConfigurationPrefs();
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
//setup mic
|
||||
if (Emulator.micPluggedIn()) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
ActivityCompat.requestPermissions(this,
|
||||
new String[]{
|
||||
Manifest.permission.RECORD_AUDIO
|
||||
},
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
onRequestPermissionsResult(0, new String[] { Manifest.permission.RECORD_AUDIO }, new int[] { PackageManager.PERMISSION_GRANTED });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean showMenu() {
|
||||
JNIdc.guiOpenSettings();
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean processJoystickInput(MotionEvent event, int axis) {
|
||||
float v = event.getAxisValue(axis);
|
||||
return InputDeviceManager.getInstance().joystickAxisEvent(event.getDeviceId(), axis, (int)Math.round(v * 32767.f));
|
||||
}
|
||||
@Override
|
||||
public boolean onGenericMotionEvent(MotionEvent event) {
|
||||
if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
boolean rc = processJoystickInput(event, MotionEvent.AXIS_X);
|
||||
rc |= processJoystickInput(event, MotionEvent.AXIS_Y);
|
||||
rc |= processJoystickInput(event, MotionEvent.AXIS_LTRIGGER);
|
||||
rc |= processJoystickInput(event, MotionEvent.AXIS_RTRIGGER);
|
||||
rc |= processJoystickInput(event, MotionEvent.AXIS_RX);
|
||||
rc |= processJoystickInput(event, MotionEvent.AXIS_RY);
|
||||
if (rc)
|
||||
return true;
|
||||
}
|
||||
else if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == InputDevice.SOURCE_CLASS_POINTER)
|
||||
{
|
||||
if (mView != null) {
|
||||
float scl = mView.getHeight() / 480.0f;
|
||||
float tx = (mView.getWidth() - 640.0f * scl) / 2;
|
||||
int xpos = Math.round((event.getX() - tx) / scl);
|
||||
int ypos = Math.round(event.getY() / scl);
|
||||
InputDeviceManager.getInstance().mouseEvent(xpos, ypos, event.getButtonState());
|
||||
}
|
||||
|
||||
}
|
||||
return super.onGenericMotionEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
if (InputDeviceManager.getInstance().joystickButtonEvent(event.getDeviceId(), keyCode, false))
|
||||
return true;
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
// FIXME
|
||||
showMenu();
|
||||
}
|
||||
if (InputDeviceManager.getInstance().joystickButtonEvent(event.getDeviceId(), keyCode, true))
|
||||
return true;
|
||||
|
||||
if (ViewConfiguration.get(this).hasPermanentMenuKey()) {
|
||||
if (keyCode == KeyEvent.KEYCODE_MENU) {
|
||||
return showMenu();
|
||||
}
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
InputDeviceManager.getInstance().stopListening();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (permissions.length > 0 && permissions[0] == Manifest.permission.RECORD_AUDIO && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
SipEmulator sip = new SipEmulator();
|
||||
sip.startRecording();
|
||||
JNIdc.setupMic(sip);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,14 +2,14 @@ package com.reicast.emulator.config;
|
|||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
|
@ -19,15 +19,15 @@ import android.widget.ImageView.ScaleType;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupWindow;
|
||||
|
||||
import com.reicast.emulator.BaseNativeGLActivity;
|
||||
import com.reicast.emulator.MainActivity;
|
||||
import com.reicast.emulator.R;
|
||||
import com.reicast.emulator.emu.GL2JNIView;
|
||||
import com.reicast.emulator.emu.JNIdc;
|
||||
import com.reicast.emulator.emu.NativeGLView;
|
||||
import com.reicast.emulator.emu.OnScreenMenu;
|
||||
import com.reicast.emulator.periph.VJoy;
|
||||
|
||||
public class EditVJoyActivity extends Activity {
|
||||
GL2JNIView mView;
|
||||
public class EditVJoyActivity extends BaseNativeGLActivity {
|
||||
PopupWindow popUp;
|
||||
LayoutParams params;
|
||||
|
||||
|
@ -51,49 +51,15 @@ public class EditVJoyActivity extends Activity {
|
|||
|
||||
String fileName = null;
|
||||
|
||||
editVjoyMode = true;
|
||||
// Call parent onCreate()
|
||||
super.onCreate(icicle);
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
if (getIntent().getAction().equals("com.reicast.EMULATOR"))
|
||||
fileName = Uri.decode(getIntent().getData().toString());
|
||||
|
||||
// Create the actual GLES view
|
||||
mView = new GL2JNIView(EditVJoyActivity.this, fileName, false,
|
||||
prefs.getInt(Config.pref_renderdepth, 24), 0, true);
|
||||
mView.setFpsDisplay(null);
|
||||
setContentView(mView);
|
||||
|
||||
vjoy_d_cached = VJoy.readCustomVjoyValues(getApplicationContext());
|
||||
|
||||
JNIdc.show_osd();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
// mView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mView.onDestroy();
|
||||
}
|
||||
|
||||
PopupWindow createVJoyPopup() {
|
||||
final PopupWindow popUp = new PopupWindow(this);
|
||||
int p = OnScreenMenu.getPixelsFromDp(60, this);
|
||||
|
|
|
@ -172,7 +172,7 @@ public class GL2JNIView extends GLSurfaceView
|
|||
|
||||
throw new EmulatorInitFailed();
|
||||
}
|
||||
JNIdc.query(ethd);
|
||||
// FIXME JNIdc.query((ethd);
|
||||
|
||||
// By default, GLSurfaceView() creates a RGB_565 opaque surface.
|
||||
// If we want a translucent one, we should change the surface's
|
||||
|
@ -570,9 +570,9 @@ public class GL2JNIView extends GLSurfaceView
|
|||
{
|
||||
gl.glViewport(0, 0, width, height);
|
||||
if (Emulator.widescreen) {
|
||||
JNIdc.rendinit(width, height);
|
||||
// FIXME JNIdc.rendinit(width, height);
|
||||
} else {
|
||||
JNIdc.rendinit(height * (4 / 3), height);
|
||||
// FIXME JNIdc.rendinit(height * (4 / 3), height);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -652,7 +652,7 @@ public class GL2JNIView extends GLSurfaceView
|
|||
Player.play();
|
||||
}
|
||||
|
||||
JNIdc.run(this);
|
||||
// FIXME JNIdc.run(this);
|
||||
}
|
||||
|
||||
int WriteBuffer(short[] samples, int wait)
|
||||
|
|
|
@ -1,22 +1,28 @@
|
|||
package com.reicast.emulator.emu;
|
||||
|
||||
import android.view.Surface;
|
||||
|
||||
import com.reicast.emulator.Emulator;
|
||||
import com.reicast.emulator.periph.SipEmulator;
|
||||
|
||||
public final class JNIdc
|
||||
{
|
||||
static { System.loadLibrary("dc"); }
|
||||
|
||||
public static native void initEnvironment(Object emulator);
|
||||
public static native void initEnvironment(Emulator emulator);
|
||||
public static native void config(String dirName);
|
||||
public static native String init(String fileName);
|
||||
public static native void query(Object thread);
|
||||
public static native void run(Object track);
|
||||
public static native void query(NativeGLView.EmuThread thread);
|
||||
public static native void run(NativeGLView.EmuThread thread);
|
||||
public static native void pause();
|
||||
public static native void resume();
|
||||
public static native void stop();
|
||||
public static native void destroy();
|
||||
|
||||
public static native int send(int cmd, int opt);
|
||||
public static native int data(int cmd, byte[] data);
|
||||
|
||||
public static native void rendinit(int w, int y);
|
||||
public static native void rendinit(Surface surface, int w, int h);
|
||||
public static native boolean rendframe();
|
||||
|
||||
public static native void vjoy(int id,float x, float y, float w, float h);
|
||||
|
@ -24,7 +30,7 @@ public final class JNIdc
|
|||
public static native void getControllers(int[] controllers, int[][] peripherals);
|
||||
public static native void initControllers(int[] controllers, int[][] peripherals);
|
||||
|
||||
public static native void setupMic(Object sip);
|
||||
public static native void setupMic(SipEmulator sip);
|
||||
public static native void diskSwap(String disk);
|
||||
public static native void vmuSwap();
|
||||
public static native void setupVmu(Object sip);
|
||||
|
|
|
@ -0,0 +1,614 @@
|
|||
package com.reicast.emulator.emu;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.media.AudioFormat;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioTrack;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Vibrator;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.reicast.emulator.Emulator;
|
||||
import com.reicast.emulator.NativeGLActivity;
|
||||
import com.reicast.emulator.R;
|
||||
import com.reicast.emulator.config.Config;
|
||||
import com.reicast.emulator.periph.InputDeviceManager;
|
||||
import com.reicast.emulator.periph.VJoy;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
public class NativeGLView extends SurfaceView {
|
||||
private static String fileName;
|
||||
private EmuThread ethd;
|
||||
private Handler handler = new Handler();
|
||||
|
||||
Vibrator vib;
|
||||
|
||||
private boolean editVjoyMode = false;
|
||||
private int selectedVjoyElement = -1;
|
||||
private ScaleGestureDetector scaleGestureDetector;
|
||||
|
||||
public float[][] vjoy_d_custom;
|
||||
|
||||
private static final float[][] vjoy = VJoy.baseVJoy();
|
||||
|
||||
private boolean touchVibrationEnabled;
|
||||
private int vibrationDuration;
|
||||
Context context;
|
||||
|
||||
public void restoreCustomVjoyValues(float[][] vjoy_d_cached) {
|
||||
vjoy_d_custom = vjoy_d_cached;
|
||||
VJoy.writeCustomVjoyValues(vjoy_d_cached, context);
|
||||
|
||||
resetEditMode();
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
public NativeGLView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public NativeGLView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public NativeGLView(final Context context, String newFileName, boolean editVjoyMode) {
|
||||
super(context);
|
||||
this.context = context;
|
||||
this.editVjoyMode = editVjoyMode;
|
||||
setKeepScreenOn(true);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
setOnSystemUiVisibilityChangeListener (new OnSystemUiVisibilityChangeListener() {
|
||||
public void onSystemUiVisibilityChange(int visibility) {
|
||||
if ((visibility & SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
|
||||
NativeGLView.this.setSystemUiVisibility(
|
||||
SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
| SYSTEM_UI_FLAG_FULLSCREEN
|
||||
| SYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
vib = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
|
||||
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||
JNIdc.screenDpi((int)Math.max(dm.xdpi, dm.ydpi));
|
||||
|
||||
JNIdc.config(prefs.getString(Config.pref_home,
|
||||
Environment.getExternalStorageDirectory().getAbsolutePath()));
|
||||
|
||||
ethd = new EmuThread(!Emulator.nosound);
|
||||
|
||||
touchVibrationEnabled = prefs.getBoolean(Config.pref_touchvibe, true);
|
||||
vibrationDuration = prefs.getInt(Config.pref_vibrationDuration, 20);
|
||||
|
||||
this.setLayerType(prefs.getInt(Config.pref_rendertype, LAYER_TYPE_HARDWARE), null);
|
||||
|
||||
vjoy_d_custom = VJoy.readCustomVjoyValues(context);
|
||||
|
||||
scaleGestureDetector = new ScaleGestureDetector(context, new OscOnScaleGestureListener());
|
||||
|
||||
// This is the game we are going to run
|
||||
fileName = newFileName;
|
||||
|
||||
if (NativeGLActivity.syms != null)
|
||||
JNIdc.data(1, NativeGLActivity.syms);
|
||||
|
||||
final String initStatus = JNIdc.init(fileName);
|
||||
if (initStatus != null)
|
||||
{
|
||||
handler.post(new Runnable() {
|
||||
public void run() {
|
||||
Log.e("initialization", "dc_init: " + initStatus);
|
||||
Toast.makeText(context, initStatus, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
throw new EmulatorInitFailed();
|
||||
}
|
||||
JNIdc.query(ethd);
|
||||
|
||||
// Set the renderer responsible for frame rendering
|
||||
//setRenderer(rend = new GL2JNIView.Renderer(this));
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// FIXME STOP AT SOME POINT!!
|
||||
if (ethd.getState() == Thread.State.TERMINATED)
|
||||
((Activity)getContext()).finish();
|
||||
else {
|
||||
JNIdc.rendframe();
|
||||
handler.post(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ethd.start();
|
||||
|
||||
}
|
||||
|
||||
private void reset_analog()
|
||||
{
|
||||
|
||||
int j=11;
|
||||
vjoy[j+1][0]=vjoy[j][0]+vjoy[j][2]/2-vjoy[j+1][2]/2;
|
||||
vjoy[j+1][1]=vjoy[j][1]+vjoy[j][3]/2-vjoy[j+1][3]/2;
|
||||
JNIdc.vjoy(j+1, vjoy[j+1][0], vjoy[j+1][1], vjoy[j+1][2], vjoy[j+1][3]);
|
||||
}
|
||||
|
||||
int get_anal(int j, int axis)
|
||||
{
|
||||
return (int) (((vjoy[j+1][axis]+vjoy[j+1][axis+2]/2) - vjoy[j][axis] - vjoy[j][axis+2]/2)*254/vjoy[j][axis+2]);
|
||||
}
|
||||
|
||||
float vbase(float p, float m, float scl)
|
||||
{
|
||||
return (int) ( m - (m -p)*scl);
|
||||
}
|
||||
|
||||
float vbase(float p, float scl)
|
||||
{
|
||||
return (int) (p*scl );
|
||||
}
|
||||
|
||||
public boolean isTablet() {
|
||||
return (getContext().getResources().getConfiguration().screenLayout
|
||||
& Configuration.SCREENLAYOUT_SIZE_MASK)
|
||||
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom)
|
||||
{
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
//dcpx/cm = dcpx/px * px/cm
|
||||
float magic = isTablet() ? 0.8f : 0.7f;
|
||||
float scl = 480.0f/getHeight() * getContext().getResources().getDisplayMetrics().density * magic;
|
||||
float scl_dc = getHeight()/480.0f;
|
||||
float tx = ((getWidth()-640.0f*scl_dc)/2)/scl_dc;
|
||||
|
||||
float a_x = -tx+ 24*scl;
|
||||
float a_y=- 24*scl;
|
||||
|
||||
float[][] vjoy_d = VJoy.getVjoy_d(vjoy_d_custom);
|
||||
|
||||
for (int i=0;i<vjoy.length;i++)
|
||||
{
|
||||
if (vjoy_d[i][0] == 288)
|
||||
vjoy[i][0] = vjoy_d[i][0];
|
||||
else if (vjoy_d[i][0]-vjoy_d_custom[getElementIdFromButtonId(i)][0] < 320)
|
||||
vjoy[i][0] = a_x + vbase(vjoy_d[i][0],scl);
|
||||
else
|
||||
vjoy[i][0] = -a_x + vbase(vjoy_d[i][0],640,scl);
|
||||
|
||||
vjoy[i][1] = a_y + vbase(vjoy_d[i][1],480,scl);
|
||||
|
||||
vjoy[i][2] = vbase(vjoy_d[i][2],scl);
|
||||
vjoy[i][3] = vbase(vjoy_d[i][3],scl);
|
||||
}
|
||||
|
||||
for (int i=0;i<VJoy.VJoyCount;i++)
|
||||
JNIdc.vjoy(i,vjoy[i][0],vjoy[i][1],vjoy[i][2],vjoy[i][3]);
|
||||
|
||||
reset_analog();
|
||||
VJoy.writeCustomVjoyValues(vjoy_d_custom, context);
|
||||
}
|
||||
|
||||
int anal_id=-1, lt_id=-1, rt_id=-1;
|
||||
|
||||
public void resetEditMode() {
|
||||
editLastX = 0;
|
||||
editLastY = 0;
|
||||
}
|
||||
|
||||
private static int getElementIdFromButtonId(int buttonId) {
|
||||
if (buttonId <= 3)
|
||||
return 0; // DPAD
|
||||
else if (buttonId <= 7)
|
||||
return 1; // X, Y, B, A Buttons
|
||||
else if (buttonId == 8)
|
||||
return 2; // Start
|
||||
else if (buttonId == 9)
|
||||
return 3; // Left Trigger
|
||||
else if (buttonId == 10)
|
||||
return 4; // Right Trigger
|
||||
else if (buttonId <= 12)
|
||||
return 5; // Analog
|
||||
else
|
||||
return 0; // DPAD diagonials
|
||||
}
|
||||
|
||||
public static int left_trigger = 0;
|
||||
public static int right_trigger = 0;
|
||||
public static int[] mouse_pos = { -32768, -32768 };
|
||||
public static int mouse_btns = 0;
|
||||
|
||||
float editLastX = 0, editLastY = 0;
|
||||
|
||||
@Override public boolean onTouchEvent(final MotionEvent event)
|
||||
{
|
||||
if (event.getSource() != InputDevice.SOURCE_TOUCHSCREEN)
|
||||
// Ignore real mice, trackballs, etc.
|
||||
return false;
|
||||
JNIdc.show_osd();
|
||||
|
||||
scaleGestureDetector.onTouchEvent(event);
|
||||
|
||||
float ty = 0.0f;
|
||||
float scl = getHeight()/480.0f;
|
||||
float tx = (getWidth()-640.0f*scl)/2;
|
||||
|
||||
int rv = 0xFFFF;
|
||||
|
||||
int aid = event.getActionMasked();
|
||||
int pid = event.getActionIndex();
|
||||
|
||||
if (!JNIdc.guiIsOpen()) {
|
||||
if (editVjoyMode && selectedVjoyElement != -1 && aid == MotionEvent.ACTION_MOVE && !scaleGestureDetector.isInProgress()) {
|
||||
float x = (event.getX() - tx) / scl;
|
||||
float y = (event.getY() - ty) / scl;
|
||||
|
||||
if (editLastX != 0 && editLastY != 0) {
|
||||
float deltaX = x - editLastX;
|
||||
float deltaY = y - editLastY;
|
||||
|
||||
vjoy_d_custom[selectedVjoyElement][0] += isTablet() ? deltaX * 2 : deltaX;
|
||||
vjoy_d_custom[selectedVjoyElement][1] += isTablet() ? deltaY * 2 : deltaY;
|
||||
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
editLastX = x;
|
||||
editLastY = y;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < event.getPointerCount(); i++) {
|
||||
float x = (event.getX(i) - tx) / scl;
|
||||
float y = (event.getY(i) - ty) / scl;
|
||||
if (anal_id != event.getPointerId(i)) {
|
||||
if (aid == MotionEvent.ACTION_POINTER_UP && pid == i)
|
||||
continue;
|
||||
for (int j = 0; j < vjoy.length; j++) {
|
||||
if (x > vjoy[j][0] && x <= (vjoy[j][0] + vjoy[j][2])) {
|
||||
/*
|
||||
//Disable pressure sensitive R/L
|
||||
//Doesn't really work properly
|
||||
|
||||
int pre=(int)(event.getPressure(i)*255);
|
||||
if (pre>20)
|
||||
{
|
||||
pre-=20;
|
||||
pre*=7;
|
||||
}
|
||||
if (pre>255) pre=255;
|
||||
*/
|
||||
|
||||
int pre = 255;
|
||||
|
||||
if (y > vjoy[j][1] && y <= (vjoy[j][1] + vjoy[j][3])) {
|
||||
if (vjoy[j][4] >= -2) {
|
||||
if (vjoy[j][5] == 0)
|
||||
if (!editVjoyMode && touchVibrationEnabled)
|
||||
vib.vibrate(vibrationDuration);
|
||||
vjoy[j][5] = 2;
|
||||
}
|
||||
|
||||
|
||||
if (vjoy[j][4] == -3) {
|
||||
if (editVjoyMode) {
|
||||
selectedVjoyElement = 5; // Analog
|
||||
resetEditMode();
|
||||
} else {
|
||||
vjoy[j + 1][0] = x - vjoy[j + 1][2] / 2;
|
||||
vjoy[j + 1][1] = y - vjoy[j + 1][3] / 2;
|
||||
|
||||
JNIdc.vjoy(j + 1, vjoy[j + 1][0], vjoy[j + 1][1], vjoy[j + 1][2], vjoy[j + 1][3]);
|
||||
anal_id = event.getPointerId(i);
|
||||
}
|
||||
} else if (vjoy[j][4] != -4) {
|
||||
if (vjoy[j][4] == -1) {
|
||||
if (editVjoyMode) {
|
||||
selectedVjoyElement = 3; // Left Trigger
|
||||
resetEditMode();
|
||||
} else {
|
||||
left_trigger = pre;
|
||||
lt_id = event.getPointerId(i);
|
||||
}
|
||||
} else if (vjoy[j][4] == -2) {
|
||||
if (editVjoyMode) {
|
||||
selectedVjoyElement = 4; // Right Trigger
|
||||
resetEditMode();
|
||||
} else {
|
||||
right_trigger = pre;
|
||||
rt_id = event.getPointerId(i);
|
||||
}
|
||||
} else {
|
||||
if (editVjoyMode) {
|
||||
selectedVjoyElement = getElementIdFromButtonId(j);
|
||||
resetEditMode();
|
||||
} else
|
||||
rv &= ~(int) vjoy[j][4];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (x < vjoy[11][0])
|
||||
x = vjoy[11][0];
|
||||
else if (x > (vjoy[11][0] + vjoy[11][2]))
|
||||
x = vjoy[11][0] + vjoy[11][2];
|
||||
|
||||
if (y < vjoy[11][1])
|
||||
y = vjoy[11][1];
|
||||
else if (y > (vjoy[11][1] + vjoy[11][3]))
|
||||
y = vjoy[11][1] + vjoy[11][3];
|
||||
|
||||
int j = 11;
|
||||
vjoy[j + 1][0] = x - vjoy[j + 1][2] / 2;
|
||||
vjoy[j + 1][1] = y - vjoy[j + 1][3] / 2;
|
||||
|
||||
JNIdc.vjoy(j + 1, vjoy[j + 1][0], vjoy[j + 1][1], vjoy[j + 1][2], vjoy[j + 1][3]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < vjoy.length; j++) {
|
||||
if (vjoy[j][5] == 2)
|
||||
vjoy[j][5] = 1;
|
||||
else if (vjoy[j][5] == 1)
|
||||
vjoy[j][5] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch(aid)
|
||||
{
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
selectedVjoyElement = -1;
|
||||
reset_analog();
|
||||
anal_id = -1;
|
||||
rv = 0xFFFF;
|
||||
right_trigger = 0;
|
||||
left_trigger = 0;
|
||||
lt_id = -1;
|
||||
rt_id = -1;
|
||||
for (int j= 0 ;j < vjoy.length; j++)
|
||||
vjoy[j][5] = 0;
|
||||
mouse_btns = 0;
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
if (event.getPointerId(event.getActionIndex())==anal_id)
|
||||
{
|
||||
reset_analog();
|
||||
anal_id = -1;
|
||||
}
|
||||
else if (event.getPointerId(event.getActionIndex())==lt_id)
|
||||
{
|
||||
left_trigger = 0;
|
||||
lt_id = -1;
|
||||
}
|
||||
else if (event.getPointerId(event.getActionIndex())==rt_id)
|
||||
{
|
||||
right_trigger = 0;
|
||||
rt_id = -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
if (event.getPointerCount() != 1)
|
||||
{
|
||||
mouse_btns = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
MotionEvent.PointerCoords pointerCoords = new MotionEvent.PointerCoords();
|
||||
event.getPointerCoords(0, pointerCoords);
|
||||
mouse_pos[0] = Math.round((pointerCoords.x - tx) / scl);
|
||||
mouse_pos[1] = Math.round(pointerCoords.y / scl);
|
||||
mouse_btns = MotionEvent.BUTTON_PRIMARY; // Mouse left button down
|
||||
}
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (event.getPointerCount() == 1)
|
||||
{
|
||||
MotionEvent.PointerCoords pointerCoords = new MotionEvent.PointerCoords();
|
||||
event.getPointerCoords(0, pointerCoords);
|
||||
mouse_pos[0] = Math.round((pointerCoords.x - tx) / scl);
|
||||
mouse_pos[1] = Math.round(pointerCoords.y / scl);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (getResources().getString(R.string.flavor).equals("naomi")) // FIXME
|
||||
{
|
||||
if (left_trigger != 0)
|
||||
rv &= ~VJoy.key_CONT_C; // Service key/coin
|
||||
}
|
||||
int joyx = get_anal(11, 0);
|
||||
int joyy = get_anal(11, 1);
|
||||
InputDeviceManager.getInstance().virtualGamepadEvent(rv, joyx, joyy, left_trigger, right_trigger);
|
||||
// Only register the mouse event if no virtual gamepad button is down
|
||||
if (!editVjoyMode && rv == 0xFFFF)
|
||||
InputDeviceManager.getInstance().mouseEvent(mouse_pos[0], mouse_pos[1], mouse_btns);
|
||||
return(true);
|
||||
}
|
||||
|
||||
private class OscOnScaleGestureListener extends
|
||||
ScaleGestureDetector.SimpleOnScaleGestureListener {
|
||||
|
||||
@Override
|
||||
public boolean onScale(ScaleGestureDetector detector) {
|
||||
if (editVjoyMode && selectedVjoyElement != -1) {
|
||||
vjoy_d_custom[selectedVjoyElement][2] *= detector.getScaleFactor();
|
||||
requestLayout();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScaleEnd(ScaleGestureDetector detector) {
|
||||
selectedVjoyElement = -1;
|
||||
}
|
||||
}
|
||||
|
||||
class EmuThread extends Thread
|
||||
{
|
||||
AudioTrack Player;
|
||||
long pos; //write position
|
||||
long size; //size in frames
|
||||
private boolean sound;
|
||||
|
||||
EmuThread(boolean sound) {
|
||||
this.sound = sound;
|
||||
}
|
||||
|
||||
@Override public void run()
|
||||
{
|
||||
if (sound) {
|
||||
int min=AudioTrack.getMinBufferSize(44100,AudioFormat.CHANNEL_OUT_STEREO,AudioFormat.ENCODING_PCM_16BIT);
|
||||
|
||||
if (2048>min)
|
||||
min=2048;
|
||||
|
||||
Player = new AudioTrack(
|
||||
AudioManager.STREAM_MUSIC,
|
||||
44100,
|
||||
AudioFormat.CHANNEL_OUT_STEREO,
|
||||
AudioFormat.ENCODING_PCM_16BIT,
|
||||
min,
|
||||
AudioTrack.MODE_STREAM
|
||||
);
|
||||
|
||||
size=min/4;
|
||||
pos=0;
|
||||
|
||||
Log.i("audcfg", "Audio streaming: buffer size " + min + " samples / " + min/44100.0 + " ms");
|
||||
Player.play();
|
||||
}
|
||||
|
||||
JNIdc.run(this);
|
||||
}
|
||||
|
||||
int WriteBuffer(short[] samples, int wait)
|
||||
{
|
||||
if (sound) {
|
||||
int newdata=samples.length/2;
|
||||
|
||||
if (wait==0)
|
||||
{
|
||||
//user bytes = write-read
|
||||
//available = size - (write - play)
|
||||
long used=pos-Player.getPlaybackHeadPosition();
|
||||
long avail=size-used;
|
||||
|
||||
//Log.i("audcfg", "u: " + used + " a: " + avail);
|
||||
if (avail<newdata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos+=newdata;
|
||||
|
||||
Player.write(samples, 0, samples.length);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void showMessage(final String msg) {
|
||||
handler.post(new Runnable() {
|
||||
public void run() {
|
||||
Log.d(context.getPackageName(), msg);
|
||||
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
int coreMessage(byte[] msg) {
|
||||
try {
|
||||
showMessage(new String(msg, "UTF-8"));
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
showMessage("coreMessage: Failed to display error");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Die() {
|
||||
showMessage("Something went wrong and reicast crashed.\nPlease report this on the reicast forums.");
|
||||
((Activity) context).finish();
|
||||
}
|
||||
|
||||
void reiosInfo(String reiosId, String reiosSoftware) {
|
||||
if (fileName != null) {
|
||||
String gameId = reiosId.replaceAll("[^a-zA-Z0-9]+", "").toLowerCase();
|
||||
SharedPreferences mPrefs = context.getSharedPreferences(gameId, Activity.MODE_PRIVATE);
|
||||
Emulator app = (Emulator) context.getApplicationContext();
|
||||
app.loadGameConfiguration(gameId);
|
||||
// if (context instanceof GL2JNIActivity)
|
||||
// ((GL2JNIActivity) context).getPad().joystick[0] = mPrefs.getBoolean(
|
||||
// Gamepad.pref_js_merged + "_A",
|
||||
// ((GL2JNIActivity) context).getPad().joystick[0]);
|
||||
mPrefs.edit().putString(Config.game_title, reiosSoftware.trim()).apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
//JNIdc.destroy();
|
||||
JNIdc.stop();
|
||||
try {
|
||||
ethd.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(19)
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
if (hasFocus && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
public static class EmulatorInitFailed extends RuntimeException {
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ public final class InputDeviceManager implements InputManager.InputDeviceListene
|
|||
|
||||
public void startListening(Context applicationContext)
|
||||
{
|
||||
maple_port = 0;
|
||||
if (applicationContext.getPackageManager().hasSystemFeature("android.hardware.touchscreen"))
|
||||
joystickAdded(VIRTUAL_GAMEPAD_ID, "Virtual Gamepad", maple_port == 3 ? 3 : maple_port++);
|
||||
int[] ids = InputDevice.getDeviceIds();
|
||||
|
|
|
@ -98,7 +98,7 @@ LOCAL_PRELINK_MODULE := false
|
|||
LOCAL_MODULE := dc
|
||||
LOCAL_DISABLE_FORMAT_STRING_CHECKS=true
|
||||
LOCAL_ASFLAGS := -fPIC -fvisibility=hidden
|
||||
LOCAL_LDLIBS := -llog -lGLESv2 -lEGL -lz
|
||||
LOCAL_LDLIBS := -llog -lGLESv2 -lEGL -lz -landroid
|
||||
#-Wl,-Map,./res/raw/syms.mp3
|
||||
LOCAL_ARM_MODE := arm
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <EGL/egl.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <types.h>
|
||||
#include <android/native_window.h>
|
||||
#include <android/native_window_jni.h>
|
||||
|
||||
#include "hw/maple/maple_cfg.h"
|
||||
#include "profiler/profiler.h"
|
||||
|
@ -42,12 +44,14 @@ JNIEXPORT jstring JNICALL Java_com_reicast_emulator_emu_JNIdc_init(JNIEnv *env,j
|
|||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_query(JNIEnv *env,jobject obj,jobject emu_thread) __attribute__((visibility("default")));
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_run(JNIEnv *env,jobject obj,jobject emu_thread) __attribute__((visibility("default")));
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_pause(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_resume(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_stop(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_destroy(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_send(JNIEnv *env,jobject obj,jint id, jint v) __attribute__((visibility("default")));
|
||||
JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_data(JNIEnv *env,jobject obj,jint id, jbyteArray d) __attribute__((visibility("default")));
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinit(JNIEnv *env,jobject obj,jint w,jint h) __attribute__((visibility("default")));
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinit(JNIEnv *env, jobject obj, jobject surface, jint w, jint h) __attribute__((visibility("default")));
|
||||
JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_emu_JNIdc_rendframe(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_vjoy(JNIEnv * env, jobject obj,u32 id,float x, float y, float w, float h) __attribute__((visibility("default")));
|
||||
|
@ -112,12 +116,16 @@ void SetApplicationPath(wchar *path);
|
|||
int dc_init(int argc, wchar* argv[]);
|
||||
void dc_run();
|
||||
void dc_pause();
|
||||
void dc_pause_emu();
|
||||
void dc_resume_emu(bool continue_running);
|
||||
void dc_stop();
|
||||
void dc_term();
|
||||
|
||||
bool VramLockedWrite(u8* address);
|
||||
|
||||
bool rend_single_frame();
|
||||
bool gles_init();
|
||||
void rend_init_renderer();
|
||||
void rend_term_renderer();
|
||||
|
||||
//extern cResetEvent rs,re;
|
||||
extern int screen_width,screen_height;
|
||||
|
@ -141,6 +149,7 @@ extern bool print_stats;
|
|||
JavaVM* g_jvm;
|
||||
jobject g_emulator;
|
||||
jmethodID saveSettingsMid;
|
||||
static ANativeWindow *g_window = 0;
|
||||
|
||||
void os_DoEvents()
|
||||
{
|
||||
|
@ -168,14 +177,12 @@ void UpdateVibration(u32 port, u32 value)
|
|||
|
||||
void *libPvr_GetRenderTarget()
|
||||
{
|
||||
// No X11 window in Android
|
||||
return(0);
|
||||
return g_window; // the surface to render to
|
||||
}
|
||||
|
||||
void *libPvr_GetRenderSurface()
|
||||
{
|
||||
// No X11 display in Android
|
||||
return(0);
|
||||
return NULL; // default display
|
||||
}
|
||||
|
||||
void common_linux_setup();
|
||||
|
@ -393,9 +400,8 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_query(JNIEnv *env,job
|
|||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_run(JNIEnv *env,jobject obj,jobject emu_thread)
|
||||
{
|
||||
install_prof_handler(0);
|
||||
|
||||
jenv = env;
|
||||
emu=emu_thread;
|
||||
emu = env->NewGlobalRef(emu_thread);
|
||||
|
||||
jsamples=env->NewShortArray(SAMPLE_COUNT*2);
|
||||
writemid=env->GetMethodID(env->GetObjectClass(emu),"WriteBuffer","([SI)I");
|
||||
|
@ -403,6 +409,8 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_run(JNIEnv *env,jobje
|
|||
dieMid=env->GetMethodID(env->GetObjectClass(emu),"Die","()V");
|
||||
|
||||
dc_run();
|
||||
|
||||
env->DeleteGlobalRef(emu);
|
||||
}
|
||||
|
||||
int msgboxf(const wchar* text,unsigned int type,...) {
|
||||
|
@ -416,10 +424,11 @@ int msgboxf(const wchar* text,unsigned int type,...) {
|
|||
va_start(args, type);
|
||||
vsprintf(temp, text, args);
|
||||
va_end(args);
|
||||
LOGE("%s", temp);
|
||||
|
||||
int byteCount = strlen(temp);
|
||||
jbyteArray bytes = jenv->NewByteArray(byteCount);
|
||||
jenv->SetByteArrayRegion(bytes, 0, byteCount, (jbyte *) temp);
|
||||
jbyteArray bytes = attacher.env->NewByteArray(byteCount);
|
||||
attacher.env->SetByteArrayRegion(bytes, 0, byteCount, (jbyte *) temp);
|
||||
|
||||
return (int)attacher.env->CallIntMethod(emu, coreMessageMid, bytes);
|
||||
}
|
||||
|
@ -441,6 +450,17 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setupVmu(JNIEnv *env,
|
|||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_pause(JNIEnv *env,jobject obj)
|
||||
{
|
||||
dc_pause();
|
||||
dc_pause_emu();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_resume(JNIEnv *env,jobject obj)
|
||||
{
|
||||
dc_resume_emu(true);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_stop(JNIEnv *env,jobject obj)
|
||||
{
|
||||
dc_stop();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_destroy(JNIEnv *env,jobject obj)
|
||||
|
@ -510,25 +530,33 @@ JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_data(JNIEnv *env, job
|
|||
return 0;
|
||||
}
|
||||
|
||||
extern void gl_swap();
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_emu_JNIdc_rendframe(JNIEnv *env,jobject obj)
|
||||
{
|
||||
return (jboolean)rend_single_frame();
|
||||
if (g_window == NULL)
|
||||
return false;
|
||||
jboolean ret = (jboolean)rend_single_frame();
|
||||
if (ret)
|
||||
gl_swap();
|
||||
return ret;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinit(JNIEnv * env, jobject obj, jint w,jint h)
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinit(JNIEnv * env, jobject obj, jobject surface, jint width, jint height)
|
||||
{
|
||||
screen_width = w;
|
||||
screen_height = h;
|
||||
|
||||
//gles_term();
|
||||
|
||||
egl_stealcntx();
|
||||
|
||||
if (!gles_init())
|
||||
die("OPENGL FAILED");
|
||||
|
||||
install_prof_handler(1);
|
||||
if (surface != NULL)
|
||||
{
|
||||
g_window = ANativeWindow_fromSurface(env, surface);
|
||||
rend_init_renderer();
|
||||
screen_width = width;
|
||||
screen_height = height;
|
||||
}
|
||||
else
|
||||
{
|
||||
rend_term_renderer();
|
||||
ANativeWindow_release(g_window);
|
||||
g_window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_vjoy(JNIEnv * env, jobject obj,u32 id,float x, float y, float w, float h)
|
||||
|
|
|
@ -206,7 +206,6 @@
|
|||
AE2A2D7F21D6851E004B308D /* 7zFile.c in Sources */ = {isa = PBXBuildFile; fileRef = AE2A2D7321D6851D004B308D /* 7zFile.c */; };
|
||||
AE2A2D8021D6851E004B308D /* 7zDec.c in Sources */ = {isa = PBXBuildFile; fileRef = AE2A2D7721D6851E004B308D /* 7zDec.c */; };
|
||||
AE2A2D8321D7DB78004B308D /* CustomTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE2A2D8121D7DB77004B308D /* CustomTexture.cpp */; };
|
||||
AE4FF4E1211588B5009BF202 /* font.png in Resources */ = {isa = PBXBuildFile; fileRef = AE4FF4E0211588B5009BF202 /* font.png */; };
|
||||
AE649BB62188689000EF4A81 /* xxhash.c in Sources */ = {isa = PBXBuildFile; fileRef = AE649BB42188689000EF4A81 /* xxhash.c */; };
|
||||
AE649BF3218C552500EF4A81 /* bitmath.c in Sources */ = {isa = PBXBuildFile; fileRef = AE649BCD218C552500EF4A81 /* bitmath.c */; };
|
||||
AE649BF4218C552500EF4A81 /* bitreader.c in Sources */ = {isa = PBXBuildFile; fileRef = AE649BCE218C552500EF4A81 /* bitreader.c */; };
|
||||
|
@ -669,7 +668,6 @@
|
|||
AE2A2D7721D6851E004B308D /* 7zDec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = 7zDec.c; sourceTree = "<group>"; };
|
||||
AE2A2D8121D7DB77004B308D /* CustomTexture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CustomTexture.cpp; sourceTree = "<group>"; };
|
||||
AE2A2D8221D7DB78004B308D /* CustomTexture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomTexture.h; sourceTree = "<group>"; };
|
||||
AE4FF4E0211588B5009BF202 /* font.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = font.png; path = ../../../linux/font.png; sourceTree = "<group>"; };
|
||||
AE649BB42188689000EF4A81 /* xxhash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xxhash.c; sourceTree = "<group>"; };
|
||||
AE649BB52188689000EF4A81 /* xxhash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xxhash.h; sourceTree = "<group>"; };
|
||||
AE649BBA218C552500EF4A81 /* all.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = all.h; sourceTree = "<group>"; };
|
||||
|
@ -945,7 +943,6 @@
|
|||
84A388B61B1CDD3E000166C0 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
AE4FF4E0211588B5009BF202 /* font.png */,
|
||||
84A388B71B1CDD3E000166C0 /* Info.plist */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
|
@ -2151,7 +2148,6 @@
|
|||
84A388BB1B1CDD3E000166C0 /* Images.xcassets in Resources */,
|
||||
84A388BE1B1CDD3E000166C0 /* MainMenu.xib in Resources */,
|
||||
AE8C274121122E2500D4D8F4 /* Changelog.txt in Resources */,
|
||||
AE4FF4E1211588B5009BF202 /* font.png in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -475,7 +475,6 @@ install: $(EXECUTABLE)
|
|||
install -m644 man/reicast-joyconfig.1 $(DESTDIR)$(MAN_DIR)
|
||||
install -m644 reicast.desktop $(DESTDIR)$(MENUENTRY_DIR)
|
||||
install -m644 reicast.png $(DESTDIR)$(ICON_DIR)
|
||||
install -m644 font.png $(DESTDIR)$(ICON_DIR)
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/$(EXECUTABLE_NAME)
|
||||
|
@ -490,7 +489,6 @@ uninstall:
|
|||
rm -f $(DESTDIR)$(MAN_DIR)/reicast-joyconfig.1
|
||||
rm -f $(DESTDIR)$(MENUENTRY_DIR)/reicast.desktop
|
||||
rm -f $(DESTDIR)$(ICON_DIR)/reicast.png
|
||||
rm -f $(DESTDIR)$(ICON_DIR)/font.png
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS) $(EXECUTABLE) $(EXECUTABLE_STRIPPED) .map
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 18 KiB |
Loading…
Reference in New Issue