From 7e26a172f400a0c565eb7d6e987af7695b4839bf Mon Sep 17 00:00:00 2001 From: Marcel Szewczyk <marcel.szewczyk@gmail.com> Date: Sat, 5 Jan 2019 17:20:47 +0100 Subject: [PATCH 01/14] Changing screen resolution: Rendering quad created --- core/rend/gles/gldraw.cpp | 86 +++++++++++++++++ core/rend/gles/gles.cpp | 198 ++++++++++++++++++++++++++++++++------ core/rend/gles/gles.h | 26 +++++ 3 files changed, 278 insertions(+), 32 deletions(-) diff --git a/core/rend/gles/gldraw.cpp b/core/rend/gles/gldraw.cpp index ded55e1d40..96194e51c4 100644 --- a/core/rend/gles/gldraw.cpp +++ b/core/rend/gles/gldraw.cpp @@ -1155,3 +1155,89 @@ void DrawStrips() #endif } } + +void fullscreenQuadPrepareFramebuffer(float scale_x, float scale_y) { + // Bind the default framebuffer + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, screen_width, screen_height); + + glDisable(GL_SCISSOR_TEST); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glDisable(GL_BLEND); + + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Reduce width to keep 4:3 aspect ratio (640x480) + u32 reducedWidth = 4 * screen_height / 3; + u32 reducedWidthOffset = (screen_width - reducedWidth) / 2; + glScissor(reducedWidthOffset, 0, reducedWidth, screen_height); + if (settings.rend.WideScreen && + (pvrrc.fb_X_CLIP.min==0) && ((pvrrc.fb_X_CLIP.max+1)/scale_x==640) && + (pvrrc.fb_Y_CLIP.min==0) && ((pvrrc.fb_Y_CLIP.max+1)/scale_y==480 )) + { + glDisable(GL_SCISSOR_TEST); + } + else + { + glEnable(GL_SCISSOR_TEST); + } +} + +void fullscreenQuadBindVertexData( + float screenToNativeX, float screenToNativeY, GLint &vsPosition, GLint &vsTexcoord, GLint &fsTexture) +{ + u32 quadVerticesNumber = 4; + glUseProgram(gl.fullscreenQuadShader); + + glBindBuffer(GL_ARRAY_BUFFER, fullscreenQuad.positionsBuffer); + glEnableVertexAttribArray( vsPosition ); + glVertexAttribPointer(vsPosition, 3, GL_FLOAT, GL_FALSE, 0, 0); + + glBindBuffer(GL_ARRAY_BUFFER, fullscreenQuad.texcoordsBuffer); + glEnableVertexAttribArray( vsTexcoord ); + const float2 texcoordsArray[] = + { + { screenToNativeX, screenToNativeY }, + { 0.0f, screenToNativeY }, + { 0.0f, 0.0f }, + { screenToNativeX, 0.0f }, + }; + glBufferData(GL_ARRAY_BUFFER, sizeof(float2) * quadVerticesNumber, texcoordsArray, GL_STATIC_DRAW); + glVertexAttribPointer(vsTexcoord, 2, GL_FLOAT, GL_FALSE, 0, 0); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, fullscreenQuad.indexBuffer); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, fullscreenQuad.framebufferTexture); + glUniform1i(fsTexture, 0); +} + +void DrawFullscreenQuad(float screenToNativeX, float screenToNativeY, float scale_x, float scale_y) { + u32 quadIndicesNumber = 6; + GLint boundArrayBuffer = 0; + GLint boundElementArrayBuffer = 0; + GLint vsPosition= glGetAttribLocation(gl.fullscreenQuadShader, "a_position"); + GLint vsTexcoord= glGetAttribLocation(gl.fullscreenQuadShader, "a_texcoord"); + GLint fsTexture = glGetUniformLocation(gl.fullscreenQuadShader, "s_texture"); + + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &boundArrayBuffer); + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &boundElementArrayBuffer); + + fullscreenQuadPrepareFramebuffer(scale_x, scale_y); + fullscreenQuadBindVertexData(screenToNativeX, screenToNativeY, vsPosition, vsTexcoord, fsTexture); + + glDrawElements(GL_TRIANGLES, quadIndicesNumber, GL_UNSIGNED_BYTE, 0); + + // Unbind buffers + glBindTexture(GL_TEXTURE_2D, 0); + glBindBuffer(GL_ARRAY_BUFFER, boundArrayBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, boundElementArrayBuffer); + glDisableVertexAttribArray( vsPosition ); + glDisableVertexAttribArray( vsTexcoord ); + + // Restore vertex attribute pointers (OSD drawing preparation) + SetupMainVBO(); +} diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index d8ec2823f9..95b73edc1c 100755 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -386,12 +386,36 @@ void main() \n\ " FRAGCOL "=vtx_base*" TEXLOOKUP "(tex,uv.st); \n\n\ }"; +const char * FullscreenQuadVertexShader = + "attribute vec3 a_position;\n\ + attribute vec2 a_texcoord;\n\ + \n\ + varying vec2 v_texcoord; \n\ + \n\ + void main()\n\ + {\n\ + v_texcoord = a_texcoord;\n\ + gl_Position = vec4(a_position, 1);\n\ + }"; + +const char * FullscreenQuadFragmentShader = + "precision mediump float;\n\ + uniform sampler2D s_texture;\n\ + \n\ + varying vec2 v_texcoord;\n\ + \n\ + void main()\n\ + {\n\ + gl_FragColor = texture2D(s_texture, v_texcoord.st);\n\ + }"; gl_ctx gl; int screen_width; int screen_height; +GLFramebufferData fullscreenQuad; + #if (HOST_OS != OS_DARWIN) && !defined(TARGET_NACL32) #if defined(GLES) && !defined(USE_SDL) // Create a basic GLES context @@ -758,7 +782,10 @@ GLuint gl_CompileShader(const char* shader,GLuint type) return rv; } -GLuint gl_CompileAndLink(const char* VertexShader, const char* FragmentShader) +GLuint gl_CompileAndLink( + const char* VertexShader, + const char* FragmentShader, + void (*bindAttribLocationCallback)(GLuint) = NULL) { //create shaders GLuint vs=gl_CompileShader(VertexShader ,GL_VERTEX_SHADER); @@ -768,15 +795,9 @@ GLuint gl_CompileAndLink(const char* VertexShader, const char* FragmentShader) glAttachShader(program, vs); glAttachShader(program, ps); - //bind vertex attribute to vbo inputs - glBindAttribLocation(program, VERTEX_POS_ARRAY, "in_pos"); - glBindAttribLocation(program, VERTEX_COL_BASE_ARRAY, "in_base"); - glBindAttribLocation(program, VERTEX_COL_OFFS_ARRAY, "in_offs"); - glBindAttribLocation(program, VERTEX_UV_ARRAY, "in_uv"); - -#ifndef GLES - glBindFragDataLocation(program, 0, "FragColor"); -#endif + if (bindAttribLocationCallback != NULL) { + bindAttribLocationCallback(program); + } glLinkProgram(program); @@ -800,6 +821,8 @@ GLuint gl_CompileAndLink(const char* VertexShader, const char* FragmentShader) die("shader compile fail\n"); } + glDetachShader(program, vs); + glDetachShader(program, ps); glDeleteShader(vs); glDeleteShader(ps); @@ -828,6 +851,65 @@ int GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode, return rv; } +void generateFullscreenQuadVertices() { + const u32 verticesNumber = 4; + const u32 indicesNumber = 6; + + const float3 quadPositions[] = + { + { 1.0f, 1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f }, + { -1.0f, -1.0f, 0.0f }, + { 1.0f, -1.0f, 0.0f }, + }; + if (!fullscreenQuad.positionsBuffer) { + glGenBuffers(1, &fullscreenQuad.positionsBuffer); + } + glBindBuffer(GL_ARRAY_BUFFER, fullscreenQuad.positionsBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(float3) * verticesNumber, quadPositions, GL_STATIC_DRAW); + + const float2 quadTexcoords[] = + { + { 1.0f, 1.0f }, + { 0.0f, 1.0f }, + { 0.0f, 0.0f }, + { 1.0f, 0.0f }, + }; + if (!fullscreenQuad.texcoordsBuffer) { + glGenBuffers(1, &fullscreenQuad.texcoordsBuffer); + } + glBindBuffer(GL_ARRAY_BUFFER, fullscreenQuad.texcoordsBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(float2) * verticesNumber, quadTexcoords, GL_STATIC_DRAW); + + const u8 quadIndices[] = + { + 0, 1, 2, + 0, 2, 3, + }; + if (!fullscreenQuad.indexBuffer) { + glGenBuffers(1, &fullscreenQuad.indexBuffer); + } + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, fullscreenQuad.indexBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(u8) * indicesNumber, quadIndices, GL_STATIC_DRAW); + + // Unbind + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} + +void bindDefaultAttribLocations(GLuint program) +{ + //bind vertex attribute to vbo inputs + glBindAttribLocation(program, VERTEX_POS_ARRAY, "in_pos"); + glBindAttribLocation(program, VERTEX_COL_BASE_ARRAY, "in_base"); + glBindAttribLocation(program, VERTEX_COL_OFFS_ARRAY, "in_offs"); + glBindAttribLocation(program, VERTEX_UV_ARRAY, "in_uv"); + +#ifndef GLES + glBindFragDataLocation(program, 0, "FragColor"); +#endif +} + bool CompilePipelineShader( PipelineShader* s) { char pshader[8192]; @@ -836,7 +918,7 @@ bool CompilePipelineShader( PipelineShader* s) s->cp_AlphaTest,s->pp_ClipTestMode,s->pp_UseAlpha, s->pp_Texture,s->pp_IgnoreTexA,s->pp_ShadInstr,s->pp_Offset,s->pp_FogCtrl); - s->program=gl_CompileAndLink(VertexShaderSource,pshader); + s->program = gl_CompileAndLink(VertexShaderSource, pshader, bindDefaultAttribLocations); //setup texture 0 as the input for the shader @@ -940,20 +1022,22 @@ bool gl_create_resources() } } - - - gl.modvol_shader.program=gl_CompileAndLink(VertexShaderSource,ModifierVolumeShader); + gl.modvol_shader.program = gl_CompileAndLink(VertexShaderSource, ModifierVolumeShader, bindDefaultAttribLocations); gl.modvol_shader.scale = glGetUniformLocation(gl.modvol_shader.program, "scale"); gl.modvol_shader.sp_ShaderColor = glGetUniformLocation(gl.modvol_shader.program, "sp_ShaderColor"); gl.modvol_shader.depth_scale = glGetUniformLocation(gl.modvol_shader.program, "depth_scale"); - - gl.OSD_SHADER.program=gl_CompileAndLink(VertexShaderSource,OSD_Shader); + gl.OSD_SHADER.program = gl_CompileAndLink(VertexShaderSource, OSD_Shader, bindDefaultAttribLocations); printf("OSD: %d\n",gl.OSD_SHADER.program); gl.OSD_SHADER.scale=glGetUniformLocation(gl.OSD_SHADER.program, "scale"); gl.OSD_SHADER.depth_scale=glGetUniformLocation(gl.OSD_SHADER.program, "depth_scale"); glUniform1i(glGetUniformLocation(gl.OSD_SHADER.program, "tex"),0); //bind osd texture to slot 0 + if (!gl.fullscreenQuadShader) { + gl.fullscreenQuadShader = gl_CompileAndLink(FullscreenQuadVertexShader, FullscreenQuadFragmentShader); + generateFullscreenQuadVertices(); + } + //#define PRECOMPILE_SHADERS #ifdef PRECOMPILE_SHADERS for (u32 i=0;i<sizeof(gl.pogram_table)/sizeof(gl.pogram_table[0]);i++) @@ -984,8 +1068,6 @@ GLuint gl_CompileShader(const char* shader,GLuint type); bool gl_create_resources(); //setup - - bool gles_init() { @@ -1015,7 +1097,12 @@ bool gles_init() return true; } - +bool isExtensionSupported(const char * name) { + if (!strstr((const char *)glGetString(GL_EXTENSIONS), name)) { + return false; + } + return true; +} float fog_coefs[]={0,0}; void tryfit(float* x,float* y) @@ -1445,6 +1532,57 @@ void OSD_DRAW() #endif } +void fullscreenQuadCreateTemporaryFBO(float &screenToNativeX, float &screenToNativeY) { + // Generate and bind a render buffer which will become a depth buffer + if (!fullscreenQuad.framebufferRenderbuffer) { + glGenRenderbuffers(1, &fullscreenQuad.framebufferRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, fullscreenQuad.framebufferRenderbuffer); +#ifdef GLES + if (isExtensionSupported("GL_OES_packed_depth_stencil")) { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, screen_width, screen_height); + } + else if (isExtensionSupported("GL_OES_depth24")) { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, screen_width, screen_height); + } + else { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width, screen_height); + } +#else + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, screen_width, screen_height); +#endif + } + + // Create a texture for rendering to - may be a color render buffer as well + if (!fullscreenQuad.framebufferTexture) { + glGenTextures(1, &fullscreenQuad.framebufferTexture); + glBindTexture(GL_TEXTURE_2D, fullscreenQuad.framebufferTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + } + + // Create the object that will allow us to render to the aforementioned texture (one for every rtt texture address) + if (!fullscreenQuad.framebuffer) { + glGenFramebuffers(1, &fullscreenQuad.framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, fullscreenQuad.framebuffer); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fullscreenQuad.framebufferTexture, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fullscreenQuad.framebufferRenderbuffer); + if (isExtensionSupported("GL_OES_packed_depth_stencil")) { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fullscreenQuad.framebufferRenderbuffer); + } + + GLuint uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); + verify(uStatus == GL_FRAMEBUFFER_COMPLETE); + } + else { + glBindFramebuffer(GL_FRAMEBUFFER, fullscreenQuad.framebuffer); + } + + glViewport(0, 0, screen_width * screenToNativeX, screen_height * screenToNativeY); +} + bool ProcessFrame(TA_context* ctx) { //disable RTTs for now .. @@ -1565,8 +1703,10 @@ bool RenderFrame() //float A=-B*max_invW+vnear; //these should be adjusted based on the current PVR scaling etc params - float dc_width=640; - float dc_height=480; + float dc_width = 640; + float dc_height = 480; + float screenToNativeX = 1; + float screenToNativeY = 1; if (!is_rtt) { @@ -1772,8 +1912,7 @@ bool RenderFrame() else { #if HOST_OS != OS_DARWIN - //Fix this in a proper way - glBindFramebuffer(GL_FRAMEBUFFER,0); + fullscreenQuadCreateTemporaryFBO(screenToNativeX, screenToNativeY); #endif } @@ -1822,15 +1961,6 @@ bool RenderFrame() printf("SCI: %f, %f, %f, %f\n", offs_x+pvrrc.fb_X_CLIP.min/scale_x,(pvrrc.fb_Y_CLIP.min/scale_y)*dc2s_scale_h,(pvrrc.fb_X_CLIP.max-pvrrc.fb_X_CLIP.min+1)/scale_x*dc2s_scale_h,(pvrrc.fb_Y_CLIP.max-pvrrc.fb_Y_CLIP.min+1)/scale_y*dc2s_scale_h); #endif - glScissor(offs_x+pvrrc.fb_X_CLIP.min/scale_x,(pvrrc.fb_Y_CLIP.min/scale_y)*dc2s_scale_h,(pvrrc.fb_X_CLIP.max-pvrrc.fb_X_CLIP.min+1)/scale_x*dc2s_scale_h,(pvrrc.fb_Y_CLIP.max-pvrrc.fb_Y_CLIP.min+1)/scale_y*dc2s_scale_h); - if (settings.rend.WideScreen && pvrrc.fb_X_CLIP.min==0 && ((pvrrc.fb_X_CLIP.max+1)/scale_x==640) && (pvrrc.fb_Y_CLIP.min==0) && ((pvrrc.fb_Y_CLIP.max+1)/scale_y==480 ) ) - { - glDisable(GL_SCISSOR_TEST); - } - else - glEnable(GL_SCISSOR_TEST); - - //restore scale_x scale_x /= scissoring_scale_x; @@ -1844,6 +1974,10 @@ bool RenderFrame() KillTex=false; + if (!is_rtt) { + DrawFullscreenQuad(screenToNativeX, screenToNativeY, scale_x, scale_y); + } + return !is_rtt; } diff --git a/core/rend/gles/gles.h b/core/rend/gles/gles.h index c77e67f5be..5859b84f5d 100755 --- a/core/rend/gles/gles.h +++ b/core/rend/gles/gles.h @@ -40,12 +40,35 @@ #define VERTEX_COL_OFFS_ARRAY 2 #define VERTEX_UV_ARRAY 3 +struct float2 +{ + float x; + float y; +}; + +struct float3 +{ + float x; + float y; + float z; +}; + +struct GLFramebufferData { + GLuint framebuffer; + GLuint framebufferRenderbuffer; + GLuint framebufferTexture; + GLuint positionsBuffer; + GLuint texcoordsBuffer; + GLuint indexBuffer; +}; //vertex types extern u32 gcflip; +extern GLFramebufferData fullscreenQuad; void DrawStrips(); +void DrawFullscreenQuad(float, float, float, float); struct PipelineShader { @@ -97,6 +120,7 @@ struct gl_ctx #endif } vbo; + GLuint fullscreenQuadShader; //GLuint matrix; }; @@ -124,3 +148,5 @@ int GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode, bool CompilePipelineShader(PipelineShader* s); #define TEXTURE_LOAD_ERROR 0 GLuint loadPNG(const string& subpath, int &width, int &height); + +void SetupMainVBO(); From 8571be39fdd2703de2cb7f904a0bcd92673b45d0 Mon Sep 17 00:00:00 2001 From: Marcel Szewczyk <marcel.szewczyk@gmail.com> Date: Sun, 6 Jan 2019 22:40:54 +0100 Subject: [PATCH 02/14] Rendering resolution lowering (horizontal and vertical) is possible from the configuration menu --- core/rend/gles/gldraw.cpp | 2 +- core/rend/gles/gles.cpp | 25 ++++++-- core/types.h | 2 + .../java/com/reicast/emulator/Emulator.java | 10 ++++ .../emulator/config/OptionsFragment.java | 46 +++++++++++++++ .../java/com/reicast/emulator/emu/JNIdc.java | 2 + .../reicast/src/main/jni/src/Android.cpp | 12 ++++ .../res/layout-v14/configure_fragment.xml | 59 +++++++++++++++++++ .../main/res/layout/configure_fragment.xml | 59 +++++++++++++++++++ .../src/main/res/values-pl/strings.xml | 3 + .../reicast/src/main/res/values/strings.xml | 3 + 11 files changed, 217 insertions(+), 6 deletions(-) diff --git a/core/rend/gles/gldraw.cpp b/core/rend/gles/gldraw.cpp index 96194e51c4..13b27b2845 100644 --- a/core/rend/gles/gldraw.cpp +++ b/core/rend/gles/gldraw.cpp @@ -1081,7 +1081,7 @@ void DrawModVols() glStencilFunc(GL_EQUAL,0x81,0x81); //only pixels that are Modvol enabled, and in area 1 //clear the stencil result bit - glStencilMask(0x3); //write to lsb + glStencilMask(0x3); //write to lsb glStencilOp(GL_ZERO,GL_ZERO,GL_ZERO); #ifndef NO_STENCIL_WORKAROUND //looks like a driver bug ? diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index 95b73edc1c..81c8f8885b 100755 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -1705,8 +1705,8 @@ bool RenderFrame() //these should be adjusted based on the current PVR scaling etc params float dc_width = 640; float dc_height = 480; - float screenToNativeX = 1; - float screenToNativeY = 1; + float screenToNativeXScale = settings.rend.HorizontalResolution / 100.0f; + float screenToNativeYScale = settings.rend.VerticalResolution / 100.0f; if (!is_rtt) { @@ -1912,7 +1912,12 @@ bool RenderFrame() else { #if HOST_OS != OS_DARWIN - fullscreenQuadCreateTemporaryFBO(screenToNativeX, screenToNativeY); + if (settings.rend.VerticalResolution == 100 && settings.rend.HorizontalResolution == 100) { + glViewport(0, 0, screen_width, screen_height); + } + else { + fullscreenQuadCreateTemporaryFBO(screenToNativeXScale, screenToNativeYScale); + } #endif } @@ -1964,6 +1969,16 @@ bool RenderFrame() //restore scale_x scale_x /= scissoring_scale_x; + if (settings.rend.VerticalResolution == 100 && settings.rend.HorizontalResolution == 100) { + glScissor(offs_x+pvrrc.fb_X_CLIP.min/scale_x,(pvrrc.fb_Y_CLIP.min/scale_y)*dc2s_scale_h,(pvrrc.fb_X_CLIP.max-pvrrc.fb_X_CLIP.min+1)/scale_x*dc2s_scale_h,(pvrrc.fb_Y_CLIP.max-pvrrc.fb_Y_CLIP.min+1)/scale_y*dc2s_scale_h); + if (settings.rend.WideScreen && pvrrc.fb_X_CLIP.min==0 && ((pvrrc.fb_X_CLIP.max+1)/scale_x==640) && (pvrrc.fb_Y_CLIP.min==0) && ((pvrrc.fb_Y_CLIP.max+1)/scale_y==480 ) ) + { + glDisable(GL_SCISSOR_TEST); + } + else + glEnable(GL_SCISSOR_TEST); + } + DrawStrips(); #if HOST_OS==OS_WINDOWS @@ -1974,8 +1989,8 @@ bool RenderFrame() KillTex=false; - if (!is_rtt) { - DrawFullscreenQuad(screenToNativeX, screenToNativeY, scale_x, scale_y); + if (!is_rtt && (settings.rend.VerticalResolution != 100 || settings.rend.HorizontalResolution != 100)) { + DrawFullscreenQuad(screenToNativeXScale, screenToNativeYScale, scale_x, scale_y); } return !is_rtt; diff --git a/core/types.h b/core/types.h index 6aa8a3c6c1..1f1cfdf65f 100644 --- a/core/types.h +++ b/core/types.h @@ -617,6 +617,8 @@ struct settings_t bool WideScreen; bool ModifierVolumes; bool Clipping; + u32 VerticalResolution; + u32 HorizontalResolution; } rend; struct diff --git a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/Emulator.java b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/Emulator.java index addb8de7ed..014b519fc4 100644 --- a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/Emulator.java +++ b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/Emulator.java @@ -26,6 +26,8 @@ public class Emulator extends Application { public static final String pref_pvrrender = "pvr_render"; public static final String pref_syncedrender = "synced_render"; public static final String pref_modvols = "modifier_volumes"; + public static final String pref_resolutionv = "resolution_vertical"; + public static final String pref_resolutionh = "resolution_horizontal"; public static final String pref_bootdisk = "boot_disk"; public static final String pref_usereios = "use_reios"; @@ -47,6 +49,8 @@ public class Emulator extends Application { public static boolean pvrrender = false; public static boolean syncedrender = false; public static boolean modvols = true; + public static int resolutionv = 100; + public static int resolutionh = 100; public static String bootdisk = null; public static boolean usereios = false; public static boolean nativeact = false; @@ -68,6 +72,8 @@ public void getConfigurationPrefs(SharedPreferences mPrefs) { Emulator.frameskip = mPrefs.getInt(pref_frameskip, frameskip); Emulator.pvrrender = mPrefs.getBoolean(pref_pvrrender, pvrrender); Emulator.syncedrender = mPrefs.getBoolean(pref_syncedrender, syncedrender); + Emulator.resolutionv = mPrefs.getInt(pref_resolutionv, resolutionv); + Emulator.resolutionh = mPrefs.getInt(pref_resolutionh, resolutionh); Emulator.bootdisk = mPrefs.getString(pref_bootdisk, bootdisk); Emulator.usereios = mPrefs.getBoolean(pref_usereios, usereios); Emulator.nativeact = mPrefs.getBoolean(pref_nativeact, nativeact); @@ -97,6 +103,8 @@ public void loadConfigurationPrefs() { JNIdc.syncedrender(Emulator.syncedrender ? 1 : 0); JNIdc.modvols(Emulator.modvols ? 1 : 0); JNIdc.usereios(Emulator.usereios ? 1 : 0); + JNIdc.frameskip(Emulator.resolutionv); + JNIdc.frameskip(Emulator.resolutionh); JNIdc.bootdisk(Emulator.bootdisk); JNIdc.dreamtime(DreamTime.getDreamtime()); } @@ -111,6 +119,8 @@ public void loadGameConfiguration(String gameId) { JNIdc.pvrrender(mPrefs.getBoolean(pref_pvrrender, pvrrender) ? 1 : 0); JNIdc.syncedrender(mPrefs.getBoolean(pref_syncedrender, syncedrender) ? 1 : 0); JNIdc.modvols(mPrefs.getBoolean(pref_modvols, modvols) ? 1 : 0); + JNIdc.resolutionv(mPrefs.getInt(pref_resolutionv, resolutionv)); + JNIdc.resolutionh(mPrefs.getInt(pref_resolutionh, resolutionh)); JNIdc.bootdisk(mPrefs.getString(pref_bootdisk, bootdisk)); } diff --git a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/OptionsFragment.java b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/OptionsFragment.java index 9b64c14cfc..17e4d20f02 100644 --- a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/OptionsFragment.java +++ b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/OptionsFragment.java @@ -432,6 +432,52 @@ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { } }); + int resolutionVertical = mPrefs.getInt(Emulator.pref_resolutionv, Emulator.resolutionv); + final String verticalText = getActivity().getString(R.string.resolution_vertical) + " "; + + final TextView resolutionVerticalView = getView().findViewById(R.id.resolutionv); + resolutionVerticalView.setText((verticalText + "(" + String.valueOf(resolutionVertical) + "%)")); + + final SeekBar resolutionVerticalSeek = getView().findViewById(R.id.resolutionv_seekbar); + resolutionVerticalSeek.setProgress(resolutionVertical - 1); + resolutionVerticalSeek.setIndeterminate(false); + resolutionVerticalSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + resolutionVerticalView.setText((verticalText + "(" + String.valueOf(progress + 1) + "%)")); + } + + public void onStartTrackingTouch(SeekBar seekBar) { + } + + public void onStopTrackingTouch(SeekBar seekBar) { + int progress = seekBar.getProgress(); + mPrefs.edit().putInt(Emulator.pref_resolutionv, progress + 1).apply(); + } + }); + + int resolutionHorizontal = mPrefs.getInt(Emulator.pref_resolutionh, Emulator.resolutionh); + final String horizontalText = getActivity().getString(R.string.resolution_horizontal) + " "; + + final TextView resolutionHorizontalView = getView().findViewById(R.id.resolutionh); + resolutionHorizontalView.setText((horizontalText + "(" + String.valueOf(resolutionHorizontal) + "%)")); + + final SeekBar resolutionHorizontalSeek = getView().findViewById(R.id.resolutionh_seekbar); + resolutionHorizontalSeek.setProgress(resolutionHorizontal - 1); + resolutionHorizontalSeek.setIndeterminate(false); + resolutionHorizontalSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + resolutionHorizontalView.setText((horizontalText + "(" + String.valueOf(progress + 1) + "%)")); + } + + public void onStartTrackingTouch(SeekBar seekBar) { + } + + public void onStopTrackingTouch(SeekBar seekBar) { + int progress = seekBar.getProgress(); + mPrefs.edit().putInt(Emulator.pref_resolutionh, progress + 1).apply(); + } + }); + OnCheckedChangeListener pvr_rendering = new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { diff --git a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/emu/JNIdc.java b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/emu/JNIdc.java index 8dc38e99ee..aa1e41f55a 100644 --- a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/emu/JNIdc.java +++ b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/emu/JNIdc.java @@ -47,6 +47,8 @@ public final class JNIdc public static native void pvrrender(int render); public static native void syncedrender(int sync); public static native void modvols(int volumes); + public static native void resolutionv(int resolutionv); + public static native void resolutionh(int resolutionv); public static native void bootdisk(String disk); public static native void usereios(int reios); public static native void dreamtime(long clock); diff --git a/shell/android-studio/reicast/src/main/jni/src/Android.cpp b/shell/android-studio/reicast/src/main/jni/src/Android.cpp index 41efebde84..b7f91b7d3d 100644 --- a/shell/android-studio/reicast/src/main/jni/src/Android.cpp +++ b/shell/android-studio/reicast/src/main/jni/src/Android.cpp @@ -63,6 +63,8 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_frameskip(JNIEnv *env JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_pvrrender(JNIEnv *env,jobject obj, jint render) __attribute__((visibility("default"))); JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_syncedrender(JNIEnv *env,jobject obj, jint sync) __attribute__((visibility("default"))); JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_modvols(JNIEnv *env,jobject obj, jint volumes) __attribute__((visibility("default"))); +JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_resolutionv(JNIEnv *env,jobject obj, jint resolutionv) __attribute__((visibility("default"))); +JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_resolutionh(JNIEnv *env,jobject obj, jint resolutionh) __attribute__((visibility("default"))); JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_bootdisk(JNIEnv *env,jobject obj, jstring disk) __attribute__((visibility("default"))); JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_usereios(JNIEnv *env,jobject obj, jint reios) __attribute__((visibility("default"))); JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_dreamtime(JNIEnv *env,jobject obj, jlong clock) __attribute__((visibility("default"))); @@ -159,6 +161,16 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_modvols(JNIEnv *env,j settings.rend.ModifierVolumes = volumes; } +JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_resolutionv(JNIEnv *env,jobject obj, jint resolutionv) +{ + settings.rend.VerticalResolution = resolutionv; +} + +JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_resolutionh(JNIEnv *env,jobject obj, jint resolutionh) +{ + settings.rend.HorizontalResolution = resolutionh; +} + JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_usereios(JNIEnv *env,jobject obj, jint reios) { settings.bios.UseReios = reios; diff --git a/shell/android-studio/reicast/src/main/res/layout-v14/configure_fragment.xml b/shell/android-studio/reicast/src/main/res/layout-v14/configure_fragment.xml index 6139526a25..2280134442 100644 --- a/shell/android-studio/reicast/src/main/res/layout-v14/configure_fragment.xml +++ b/shell/android-studio/reicast/src/main/res/layout-v14/configure_fragment.xml @@ -719,6 +719,65 @@ </LinearLayout> </TableRow> + <TableRow + android:layout_marginTop="10dp" + android:gravity="center_vertical" > + + <TextView + android:id="@+id/resolution" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="center_vertical|left" + android:text="@string/resolution" /> + </TableRow> + + <TableRow + android:layout_marginTop="5dp" + android:gravity="center_vertical" > + + <TextView + android:id="@+id/resolutionh" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="center_vertical|left" + android:text="@string/resolution_horizontal" /> + + <SeekBar + android:id="@+id/resolutionh_seekbar" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:ems="10" + android:gravity="center_vertical|left" + android:max="99" + android:progress="99" /> + </TableRow> + + <TableRow + android:layout_marginTop="5dp" + android:gravity="center_vertical" > + + <TextView + android:id="@+id/resolutionv" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="center_vertical|left" + android:text="@string/resolution_vertical" /> + + <SeekBar + android:id="@+id/resolutionv_seekbar" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:ems="10" + android:gravity="center_vertical|left" + android:max="99" + android:progress="99" /> + </TableRow> + <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/shell/android-studio/reicast/src/main/res/layout/configure_fragment.xml b/shell/android-studio/reicast/src/main/res/layout/configure_fragment.xml index d4dfcc2450..ebed4f7edc 100644 --- a/shell/android-studio/reicast/src/main/res/layout/configure_fragment.xml +++ b/shell/android-studio/reicast/src/main/res/layout/configure_fragment.xml @@ -719,6 +719,65 @@ </LinearLayout> </TableRow> + <TableRow + android:layout_marginTop="10dp" + android:gravity="center_vertical" > + + <TextView + android:id="@+id/resolution" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="center_vertical|left" + android:text="@string/resolution" /> + </TableRow> + + <TableRow + android:layout_marginTop="5dp" + android:gravity="center_vertical" > + + <TextView + android:id="@+id/resolutionh" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="center_vertical|left" + android:text="@string/resolution_horizontal" /> + + <SeekBar + android:id="@+id/resolutionh_seekbar" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:ems="10" + android:gravity="center_vertical|left" + android:max="100" + android:progress="100" /> + </TableRow> + + <TableRow + android:layout_marginTop="5dp" + android:gravity="center_vertical" > + + <TextView + android:id="@+id/resolutionv" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="center_vertical|left" + android:text="@string/resolution_vertical" /> + + <SeekBar + android:id="@+id/resolutionv_seekbar" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:ems="10" + android:gravity="center_vertical|left" + android:max="100" + android:progress="100" /> + </TableRow> + <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/shell/android-studio/reicast/src/main/res/values-pl/strings.xml b/shell/android-studio/reicast/src/main/res/values-pl/strings.xml index 5d5e9bb2a1..17275683ea 100644 --- a/shell/android-studio/reicast/src/main/res/values-pl/strings.xml +++ b/shell/android-studio/reicast/src/main/res/values-pl/strings.xml @@ -23,6 +23,9 @@ <string name="select_stretch">Tryb Szerokoekranowy</string> <string name="set_frameskip">Wartość Frameskip</string> <string name="select_render">PVR Rendering (na razie nie działa)</string> + <string name="resolution">Rozdzielczość (mniej = szybciej)</string> + <string name="resolution_vertical">Pionowa</string> + <string name="resolution_horizontal">Pozioma</string> <string name="games_listing">Dostępne gry Dreamcast\'a</string> diff --git a/shell/android-studio/reicast/src/main/res/values/strings.xml b/shell/android-studio/reicast/src/main/res/values/strings.xml index 25d6a427fa..229daa246f 100644 --- a/shell/android-studio/reicast/src/main/res/values/strings.xml +++ b/shell/android-studio/reicast/src/main/res/values/strings.xml @@ -54,6 +54,9 @@ <string name="select_software">Use Software Layer</string> <string name="select_sound">Disable Emulator Sound</string> <string name="select_depth">View Rendering Depth</string> + <string name="resolution">Resolution (lower = faster)</string> + <string name="resolution_vertical">Vertical</string> + <string name="resolution_horizontal">Horizontal</string> <string name="boot_disk">Boot Disk (ie. Gameshark, Utopia)</string> <string name="reset_emu">Reset Emu</string> From e285d7f9ba1ba174a2c9f7b2d1d164700b1e4ff7 Mon Sep 17 00:00:00 2001 From: Marcel Szewczyk <marcel.szewczyk@gmail.com> Date: Tue, 8 Jan 2019 23:35:48 +0100 Subject: [PATCH 03/14] Additional improvements to lowering rendering resolution feature --- core/rend/gles/gldraw.cpp | 24 +++++++++---------- core/rend/gles/gles.cpp | 4 ++-- core/rend/gles/gles.h | 2 -- .../java/com/reicast/emulator/Emulator.java | 4 ++-- .../emulator/config/OptionsFragment.java | 2 ++ 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/core/rend/gles/gldraw.cpp b/core/rend/gles/gldraw.cpp index 13b27b2845..96788085cd 100644 --- a/core/rend/gles/gldraw.cpp +++ b/core/rend/gles/gldraw.cpp @@ -1156,7 +1156,7 @@ void DrawStrips() } } -void fullscreenQuadPrepareFramebuffer(float scale_x, float scale_y) { +void fullscreenQuadPrepareFramebuffer(float xScale, float yScale) { // Bind the default framebuffer glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0, 0, screen_width, screen_height); @@ -1175,8 +1175,8 @@ void fullscreenQuadPrepareFramebuffer(float scale_x, float scale_y) { u32 reducedWidthOffset = (screen_width - reducedWidth) / 2; glScissor(reducedWidthOffset, 0, reducedWidth, screen_height); if (settings.rend.WideScreen && - (pvrrc.fb_X_CLIP.min==0) && ((pvrrc.fb_X_CLIP.max+1)/scale_x==640) && - (pvrrc.fb_Y_CLIP.min==0) && ((pvrrc.fb_Y_CLIP.max+1)/scale_y==480 )) + (pvrrc.fb_X_CLIP.min==0) && ((pvrrc.fb_X_CLIP.max+1)/xScale==640) && + (pvrrc.fb_Y_CLIP.min==0) && ((pvrrc.fb_Y_CLIP.max+1)/yScale==480 )) { glDisable(GL_SCISSOR_TEST); } @@ -1186,8 +1186,8 @@ void fullscreenQuadPrepareFramebuffer(float scale_x, float scale_y) { } } -void fullscreenQuadBindVertexData( - float screenToNativeX, float screenToNativeY, GLint &vsPosition, GLint &vsTexcoord, GLint &fsTexture) +void fullscreenQuadBindVertexData(float screenToNativeXScale, float screenToNativeYScale, + GLint & vsPosition, GLint & vsTexcoord, GLint & fsTexture) { u32 quadVerticesNumber = 4; glUseProgram(gl.fullscreenQuadShader); @@ -1200,10 +1200,10 @@ void fullscreenQuadBindVertexData( glEnableVertexAttribArray( vsTexcoord ); const float2 texcoordsArray[] = { - { screenToNativeX, screenToNativeY }, - { 0.0f, screenToNativeY }, - { 0.0f, 0.0f }, - { screenToNativeX, 0.0f }, + { screenToNativeXScale, screenToNativeYScale }, + { 0.0f, screenToNativeYScale }, + { 0.0f, 0.0f }, + { screenToNativeXScale, 0.0f }, }; glBufferData(GL_ARRAY_BUFFER, sizeof(float2) * quadVerticesNumber, texcoordsArray, GL_STATIC_DRAW); glVertexAttribPointer(vsTexcoord, 2, GL_FLOAT, GL_FALSE, 0, 0); @@ -1215,7 +1215,7 @@ void fullscreenQuadBindVertexData( glUniform1i(fsTexture, 0); } -void DrawFullscreenQuad(float screenToNativeX, float screenToNativeY, float scale_x, float scale_y) { +void DrawFullscreenQuad(float screenToNativeXScale, float screenToNativeYScale, float xScale, float yScale) { u32 quadIndicesNumber = 6; GLint boundArrayBuffer = 0; GLint boundElementArrayBuffer = 0; @@ -1226,8 +1226,8 @@ void DrawFullscreenQuad(float screenToNativeX, float screenToNativeY, float scal glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &boundArrayBuffer); glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &boundElementArrayBuffer); - fullscreenQuadPrepareFramebuffer(scale_x, scale_y); - fullscreenQuadBindVertexData(screenToNativeX, screenToNativeY, vsPosition, vsTexcoord, fsTexture); + fullscreenQuadPrepareFramebuffer(xScale, yScale); + fullscreenQuadBindVertexData(screenToNativeXScale, screenToNativeYScale, vsPosition, vsTexcoord, fsTexture); glDrawElements(GL_TRIANGLES, quadIndicesNumber, GL_UNSIGNED_BYTE, 0); diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index 81c8f8885b..61943c79ce 100755 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -1532,7 +1532,7 @@ void OSD_DRAW() #endif } -void fullscreenQuadCreateTemporaryFBO(float &screenToNativeX, float &screenToNativeY) { +void fullscreenQuadCreateTemporaryFBO(float & screenToNativeXScale, float & screenToNativeY) { // Generate and bind a render buffer which will become a depth buffer if (!fullscreenQuad.framebufferRenderbuffer) { glGenRenderbuffers(1, &fullscreenQuad.framebufferRenderbuffer); @@ -1580,7 +1580,7 @@ void fullscreenQuadCreateTemporaryFBO(float &screenToNativeX, float &screenToNat glBindFramebuffer(GL_FRAMEBUFFER, fullscreenQuad.framebuffer); } - glViewport(0, 0, screen_width * screenToNativeX, screen_height * screenToNativeY); + glViewport(0, 0, screen_width * screenToNativeXScale, screen_height * screenToNativeY); } bool ProcessFrame(TA_context* ctx) diff --git a/core/rend/gles/gles.h b/core/rend/gles/gles.h index 5859b84f5d..2d039a6379 100755 --- a/core/rend/gles/gles.h +++ b/core/rend/gles/gles.h @@ -148,5 +148,3 @@ int GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode, bool CompilePipelineShader(PipelineShader* s); #define TEXTURE_LOAD_ERROR 0 GLuint loadPNG(const string& subpath, int &width, int &height); - -void SetupMainVBO(); diff --git a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/Emulator.java b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/Emulator.java index 014b519fc4..ea1f0263a3 100644 --- a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/Emulator.java +++ b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/Emulator.java @@ -103,8 +103,8 @@ public void loadConfigurationPrefs() { JNIdc.syncedrender(Emulator.syncedrender ? 1 : 0); JNIdc.modvols(Emulator.modvols ? 1 : 0); JNIdc.usereios(Emulator.usereios ? 1 : 0); - JNIdc.frameskip(Emulator.resolutionv); - JNIdc.frameskip(Emulator.resolutionh); + JNIdc.resolutionv(Emulator.resolutionv); + JNIdc.resolutionh(Emulator.resolutionh); JNIdc.bootdisk(Emulator.bootdisk); JNIdc.dreamtime(DreamTime.getDreamtime()); } diff --git a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/OptionsFragment.java b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/OptionsFragment.java index 17e4d20f02..61c6ddcd28 100644 --- a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/OptionsFragment.java +++ b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/OptionsFragment.java @@ -745,6 +745,8 @@ private void resetEmuSettings() { mPrefs.edit().remove(Emulator.pref_frameskip).apply(); mPrefs.edit().remove(Emulator.pref_pvrrender).apply(); mPrefs.edit().remove(Emulator.pref_syncedrender).apply(); + mPrefs.edit().remove(Emulator.pref_resolutionv).apply(); + mPrefs.edit().remove(Emulator.pref_resolutionh).apply(); mPrefs.edit().remove(Emulator.pref_bootdisk).apply(); mPrefs.edit().remove(Config.pref_showfps).apply(); mPrefs.edit().remove(Config.pref_rendertype).apply(); From 2327c1b83e3cabb0069c349151a4ad6cd09a33d0 Mon Sep 17 00:00:00 2001 From: Marcel Szewczyk <marcel.szewczyk@gmail.com> Date: Wed, 9 Jan 2019 17:20:09 +0100 Subject: [PATCH 04/14] nullDC.cpp updated to support other OSes --- core/nullDC.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 860fa43408..c7e2c47448 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -299,6 +299,10 @@ void LoadSettings() settings.rend.UseMipmaps = cfgLoadInt("config", "rend.UseMipmaps", 1); settings.rend.WideScreen = cfgLoadInt("config", "rend.WideScreen", 0); settings.rend.Clipping = cfgLoadInt("config", "rend.Clipping", 1); + settings.rend. + VerticalResolution = cfgLoadInt("config", "rend.VerticalResolution", 100); + settings.rend. + HorizontalResolution = cfgLoadInt("config", "rend.HorizontalResolution", 100); settings.pvr.subdivide_transp = cfgLoadInt("config", "pvr.Subdivide", 0); @@ -366,6 +370,10 @@ void LoadCustom() settings.dynarec.safemode = cfgGameInt(reios_id,"Dynarec.safemode", settings.dynarec.safemode); settings.rend.ModifierVolumes = cfgGameInt(reios_id,"rend.ModifierVolumes", settings.rend.ModifierVolumes); settings.rend.Clipping = cfgGameInt(reios_id,"rend.Clipping", settings.rend.Clipping); + settings.rend. + VerticalResolution = cfgGameInt(reios_id, "rend.VerticalResolution", settings.rend.VerticalResolution); + settings.rend. + HorizontalResolution = cfgGameInt(reios_id, "rend.HorizontalResolution", settings.rend.HorizontalResolution); settings.pvr.subdivide_transp = cfgGameInt(reios_id,"pvr.Subdivide", settings.pvr.subdivide_transp); From 82bbe690b1171e5a9fdccb4ea52bc8e84ff943f5 Mon Sep 17 00:00:00 2001 From: Marcel Szewczyk <marcel.szewczyk@gmail.com> Date: Sun, 13 Jan 2019 17:33:23 +0100 Subject: [PATCH 05/14] Stencil support for OpenGL added - requires OpenGL >= 3 --- core/rend/gles/gles.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index 5415c7544b..578538fdd8 100755 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -1601,7 +1601,8 @@ void fullscreenQuadCreateTemporaryFBO(float & screenToNativeXScale, float & scre glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width, screen_height); } #else - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, screen_width, screen_height); + //OpenGL >= 3.0 is required + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, screen_width, screen_height); #endif } @@ -1622,10 +1623,14 @@ void fullscreenQuadCreateTemporaryFBO(float & screenToNativeXScale, float & scre glBindFramebuffer(GL_FRAMEBUFFER, fullscreenQuad.framebuffer); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fullscreenQuad.framebufferTexture, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fullscreenQuad.framebufferRenderbuffer); +#ifdef GLES if (isExtensionSupported("GL_OES_packed_depth_stencil")) { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fullscreenQuad.framebufferRenderbuffer); } - +#else + //OpenGL >= 3.0 is required + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fullscreenQuad.framebufferRenderbuffer); +#endif GLuint uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); verify(uStatus == GL_FRAMEBUFFER_COMPLETE); } From a60286cc0f8e25da9af6580b8b036382feeeb956 Mon Sep 17 00:00:00 2001 From: Marcel Szewczyk <marcel.szewczyk@gmail.com> Date: Sun, 13 Jan 2019 18:15:26 +0100 Subject: [PATCH 06/14] Single render scale factor seekbar --- .../emulator/config/OptionsFragment.java | 39 +++++-------------- .../res/layout-v14/configure_fragment.xml | 33 +--------------- .../main/res/layout/configure_fragment.xml | 37 ++---------------- 3 files changed, 13 insertions(+), 96 deletions(-) diff --git a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/OptionsFragment.java b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/OptionsFragment.java index f13e687509..4abdaa198b 100644 --- a/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/OptionsFragment.java +++ b/shell/android-studio/reicast/src/main/java/com/reicast/emulator/config/OptionsFragment.java @@ -411,17 +411,17 @@ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { }); int resolutionVertical = mPrefs.getInt(Emulator.pref_resolutionv, Emulator.resolutionv); - final String verticalText = getActivity().getString(R.string.resolution_vertical) + " "; + final String resolutionText = getActivity().getString(R.string.resolution) + ": "; - final TextView resolutionVerticalView = getView().findViewById(R.id.resolutionv); - resolutionVerticalView.setText((verticalText + "(" + String.valueOf(resolutionVertical) + "%)")); + final TextView resolutionTextView = getView().findViewById(R.id.resolution); + resolutionTextView.setText((resolutionText + String.valueOf(resolutionVertical) + "%")); - final SeekBar resolutionVerticalSeek = getView().findViewById(R.id.resolutionv_seekbar); - resolutionVerticalSeek.setProgress(resolutionVertical - 1); - resolutionVerticalSeek.setIndeterminate(false); - resolutionVerticalSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { + final SeekBar resolutionVHSeek = getView().findViewById(R.id.resolutionvh_seekbar); + resolutionVHSeek.setProgress(resolutionVertical - 1); //can take vertical OR horizontal (the same values) + resolutionVHSeek.setIndeterminate(false); + resolutionVHSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - resolutionVerticalView.setText((verticalText + "(" + String.valueOf(progress + 1) + "%)")); + resolutionTextView.setText((resolutionText + String.valueOf(progress + 1) + "%")); } public void onStartTrackingTouch(SeekBar seekBar) { @@ -429,29 +429,8 @@ public void onStartTrackingTouch(SeekBar seekBar) { public void onStopTrackingTouch(SeekBar seekBar) { int progress = seekBar.getProgress(); + //the same progress for both resolutions mPrefs.edit().putInt(Emulator.pref_resolutionv, progress + 1).apply(); - } - }); - - int resolutionHorizontal = mPrefs.getInt(Emulator.pref_resolutionh, Emulator.resolutionh); - final String horizontalText = getActivity().getString(R.string.resolution_horizontal) + " "; - - final TextView resolutionHorizontalView = getView().findViewById(R.id.resolutionh); - resolutionHorizontalView.setText((horizontalText + "(" + String.valueOf(resolutionHorizontal) + "%)")); - - final SeekBar resolutionHorizontalSeek = getView().findViewById(R.id.resolutionh_seekbar); - resolutionHorizontalSeek.setProgress(resolutionHorizontal - 1); - resolutionHorizontalSeek.setIndeterminate(false); - resolutionHorizontalSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - resolutionHorizontalView.setText((horizontalText + "(" + String.valueOf(progress + 1) + "%)")); - } - - public void onStartTrackingTouch(SeekBar seekBar) { - } - - public void onStopTrackingTouch(SeekBar seekBar) { - int progress = seekBar.getProgress(); mPrefs.edit().putInt(Emulator.pref_resolutionh, progress + 1).apply(); } }); diff --git a/shell/android-studio/reicast/src/main/res/layout-v14/configure_fragment.xml b/shell/android-studio/reicast/src/main/res/layout-v14/configure_fragment.xml index 600f8a080d..bb8f13fcce 100644 --- a/shell/android-studio/reicast/src/main/res/layout-v14/configure_fragment.xml +++ b/shell/android-studio/reicast/src/main/res/layout-v14/configure_fragment.xml @@ -738,39 +738,8 @@ android:layout_marginTop="5dp" android:gravity="center_vertical" > - <TextView - android:id="@+id/resolutionh" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="1" - android:gravity="center_vertical|left" - android:text="@string/resolution_horizontal" /> - - <SeekBar - android:id="@+id/resolutionh_seekbar" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="1" - android:ems="10" - android:gravity="center_vertical|left" - android:max="99" - android:progress="99" /> - </TableRow> - - <TableRow - android:layout_marginTop="5dp" - android:gravity="center_vertical" > - - <TextView - android:id="@+id/resolutionv" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="1" - android:gravity="center_vertical|left" - android:text="@string/resolution_vertical" /> - <SeekBar - android:id="@+id/resolutionv_seekbar" + android:id="@+id/resolutionvh_seekbar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" diff --git a/shell/android-studio/reicast/src/main/res/layout/configure_fragment.xml b/shell/android-studio/reicast/src/main/res/layout/configure_fragment.xml index cb35c6024b..4481ed8482 100644 --- a/shell/android-studio/reicast/src/main/res/layout/configure_fragment.xml +++ b/shell/android-studio/reicast/src/main/res/layout/configure_fragment.xml @@ -738,46 +738,15 @@ android:layout_marginTop="5dp" android:gravity="center_vertical" > - <TextView - android:id="@+id/resolutionh" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="1" - android:gravity="center_vertical|left" - android:text="@string/resolution_horizontal" /> - - <SeekBar - android:id="@+id/resolutionh_seekbar" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="1" - android:ems="10" - android:gravity="center_vertical|left" - android:max="100" - android:progress="100" /> - </TableRow> - - <TableRow - android:layout_marginTop="5dp" - android:gravity="center_vertical" > - - <TextView - android:id="@+id/resolutionv" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="1" - android:gravity="center_vertical|left" - android:text="@string/resolution_vertical" /> - <SeekBar - android:id="@+id/resolutionv_seekbar" + android:id="@+id/resolutionvh_seekbar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:ems="10" android:gravity="center_vertical|left" - android:max="100" - android:progress="100" /> + android:max="99" + android:progress="99" /> </TableRow> <LinearLayout From 347fcf5c6c5ef57b7bb6b48352e1fc7230b66717 Mon Sep 17 00:00:00 2001 From: "Christoph \"baka0815\" Schwerdtfeger" <git@baka0815.de> Date: Wed, 16 Jan 2019 19:04:32 +0100 Subject: [PATCH 07/14] ALSA: make device configurable Trying to load the device from the emu.cfg and if not set (should be the default for everyone currently) use the existing procedure to try to determine the device (default > plughw:0,0,0 > plughw:0,0). --- core/oslib/audiobackend_alsa.cpp | 42 ++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/core/oslib/audiobackend_alsa.cpp b/core/oslib/audiobackend_alsa.cpp index 870682e53d..099d13a5fe 100644 --- a/core/oslib/audiobackend_alsa.cpp +++ b/core/oslib/audiobackend_alsa.cpp @@ -1,6 +1,7 @@ #include "oslib/audiobackend_alsa.h" #if USE_ALSA #include <alsa/asoundlib.h> +#include "cfg/cfg.h" snd_pcm_t *handle; @@ -16,21 +17,46 @@ static void alsa_init() int dir=-1; snd_pcm_uframes_t frames; - /* Open PCM device for playback. */ - int rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0); + string device = cfgLoadStr("alsa", "device", ""); - if (rc<0) - rc = snd_pcm_open(&handle, "plughw:0,0,0", SND_PCM_STREAM_PLAYBACK, 0); - - if (rc<0) - rc = snd_pcm_open(&handle, "plughw:0,0", SND_PCM_STREAM_PLAYBACK, 0); + int rc = -1; + if (device == "") + { + printf("ALSA: trying to determine audio device\n"); + /* Open PCM device for playback. */ + device = "default"; + rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0); + + if (rc < 0) + { + device = "plughw:0,0,0"; + rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0); + } + + if (rc < 0) + { + device = "plughw:0,0"; + rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0); + } + + if (rc >= 0) + { + // init successfull, write value back to config + cfgSaveStr("alsa", "device", device.c_str()); + } + } + else { + rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0); + } if (rc < 0) { - fprintf(stderr, "unable to open PCM device: %s\n", snd_strerror(rc)); + fprintf(stderr, "unable to open PCM device %s: %s\n", device.c_str(), snd_strerror(rc)); return; } + printf("ALSA: Successfully initialized \"%s\"\n", device.c_str()); + /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); From 1b8f45c7519d6b625159b3146829cda4c4d47090 Mon Sep 17 00:00:00 2001 From: "Christoph \"baka0815\" Schwerdtfeger" <git@baka0815.de> Date: Wed, 16 Jan 2019 19:14:37 +0100 Subject: [PATCH 08/14] ALSA: remove unused variables loops and size are unused, so just remove them while we're here. --- core/oslib/audiobackend_alsa.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/oslib/audiobackend_alsa.cpp b/core/oslib/audiobackend_alsa.cpp index 099d13a5fe..25fa11325e 100644 --- a/core/oslib/audiobackend_alsa.cpp +++ b/core/oslib/audiobackend_alsa.cpp @@ -8,10 +8,6 @@ snd_pcm_t *handle; // We're making these functions static - there's no need to pollute the global namespace static void alsa_init() { - - long loops; - int size; - snd_pcm_hw_params_t *params; unsigned int val; int dir=-1; From 108e840324f06a01a2791ae25e498f802d09cf03 Mon Sep 17 00:00:00 2001 From: "Christoph \"baka0815\" Schwerdtfeger" <git@baka0815.de> Date: Wed, 16 Jan 2019 20:48:32 +0100 Subject: [PATCH 09/14] SDL: rumble support This adds support for rumble to the SDL backend. It does not however attach a purupuru/rumble pack --- core/linux-dist/main.cpp | 27 ++++++++----- core/sdl/sdl.cpp | 87 ++++++++++++++++++++++++++++++++++++---- core/sdl/sdl.h | 1 + 3 files changed, 97 insertions(+), 18 deletions(-) diff --git a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp index 5394e207f0..b8d30ce8bf 100644 --- a/core/linux-dist/main.cpp +++ b/core/linux-dist/main.cpp @@ -144,25 +144,30 @@ void UpdateInputState(u32 port) void UpdateVibration(u32 port, u32 value) { - #if defined(USE_EVDEV) - u8 POW_POS = (value >> 8) & 0x3; - u8 POW_NEG = (value >> 12) & 0x3; - u8 FREQ = (value >> 16) & 0xFF; + u8 POW_POS = (value >> 8) & 0x3; + u8 POW_NEG = (value >> 12) & 0x3; + u8 FREQ = (value >> 16) & 0xFF; - double pow = (POW_POS + POW_NEG) / 7.0; - double pow_l = pow * (0x3B - FREQ) / 17.0; - double pow_r = pow * (FREQ - 0x07) / 15.0; + double pow = (POW_POS + POW_NEG) / 7.0; + double pow_l = pow * (0x3B - FREQ) / 17.0; + double pow_r = pow * (FREQ - 0x07) / 15.0; - if (pow_l > 1.0) pow_l = 1.0; - if (pow_r > 1.0) pow_r = 1.0; + if (pow_l > 1.0) pow_l = 1.0; + if (pow_r > 1.0) pow_r = 1.0; - u16 pow_strong = (u16)(65535 * pow_l); - u16 pow_weak = (u16)(65535 * pow_r); + u16 pow_strong = (u16)(65535 * pow_l); + u16 pow_weak = (u16)(65535 * pow_r); + #if defined(USE_EVDEV) input_evdev_rumble(port, pow_strong, pow_weak); #endif + + #if defined(USE_SDL) + input_sdl_rumble(port, pow_strong, pow_weak); + #endif } + void os_DoEvents() { #if defined(SUPPORT_X11) diff --git a/core/sdl/sdl.cpp b/core/sdl/sdl.cpp index c61fc1dad3..15ace1b5fc 100644 --- a/core/sdl/sdl.cpp +++ b/core/sdl/sdl.cpp @@ -54,27 +54,39 @@ const u32* sdl_map_axis = sdl_map_axis_usb; u32 JSensitivity[256]; // To have less sensitive value on nubs #endif +bool haptic_init = false; +static SDL_Haptic* haptic = NULL; +int effect_id = 0; + void input_sdl_init() { - if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) + u32 subsystem_init = SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC); + + if ((subsystem_init & SDL_INIT_JOYSTICK) == 0) { if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) { - die("error initializing SDL Joystick subsystem"); + die("SDL: error initializing Joystick subsystem"); } } + + // Trying to initialize haptic subsystem (rumble) + if ((subsystem_init & SDL_INIT_HAPTIC) == 0) + { + haptic_init = (SDL_InitSubSystem(SDL_INIT_HAPTIC) == 0); + } + // Open joystick device int numjoys = SDL_NumJoysticks(); - printf("Number of Joysticks found = %i\n", numjoys); + printf("SDL: Number of Joysticks found = %i\n", numjoys); if (numjoys > 0) { JoySDL = SDL_JoystickOpen(0); } - printf("Joystick opened\n"); - if (JoySDL) { + printf("SDL: Joystick opened\n"); int AxisCount,ButtonCount; const char* Name; @@ -87,14 +99,21 @@ void input_sdl_init() Name = SDL_JoystickName(JoySDL); printf("SDL: Found '%s' joystick with %d axes and %d buttons\n", Name, AxisCount, ButtonCount); + if (haptic_init) + { + if (SDL_JoystickIsHaptic(JoySDL) == SDL_TRUE) + printf("SDL: Rumble support available\n"); + else + printf("SDL: Rumble support NOT available\n"); + } if (Name != NULL && strcmp(Name,"Microsoft X-Box 360 pad")==0) { sdl_map_btn = sdl_map_btn_xbox360; sdl_map_axis = sdl_map_axis_xbox360; - printf("Using Xbox 360 map\n"); + printf("SDL: Using Xbox 360 map\n"); } - + // Create the first controller with two VMUs // (only when evdev is not available as it's already configured via evdev then) // TODO: make this configurable @@ -402,6 +421,60 @@ void input_sdl_handle(u32 port) } } +void input_sdl_rumble(u32 port, u16 pow_strong, u16 pow_weak) +{ + // No haptic supported, no need for rumble + if (!haptic_init) + return; + + // If already open, close it to stop the current rumble effect + if (haptic) + { + if (effect_id != 0) + { + SDL_HapticStopEffect( haptic, effect_id ); + SDL_HapticDestroyEffect( haptic, effect_id ); + effect_id = 0; + } + + SDL_HapticClose(haptic); + haptic = NULL; + } + + // Open the device + if (!haptic) + haptic = SDL_HapticOpenFromJoystick( JoySDL ); + + if (!haptic) + return; + + // Check if the haptic supports the left/right effect + if ((SDL_HapticQuery(haptic) & SDL_HAPTIC_LEFTRIGHT) == 0) + { + SDL_HapticClose(haptic); + haptic = NULL; + + // Disable haptic/rumble + haptic_init = false; + + return; + } + + // Create the effect + SDL_HapticEffect effect; + SDL_memset(&effect, 0, sizeof(SDL_HapticEffect) ); // 0 is safe default + effect.type = SDL_HAPTIC_LEFTRIGHT; + effect.leftright.large_magnitude = pow_strong; + effect.leftright.small_magnitude = pow_weak; + effect.leftright.length = 0; + + // Upload the effect + effect_id = SDL_HapticNewEffect(haptic, &effect); + + // Let's play the effect + SDL_HapticRunEffect(haptic, effect_id, 1); +} + void sdl_window_set_text(const char* text) { #ifdef TARGET_PANDORA diff --git a/core/sdl/sdl.h b/core/sdl/sdl.h index ce15507184..d85095e59a 100644 --- a/core/sdl/sdl.h +++ b/core/sdl/sdl.h @@ -3,5 +3,6 @@ extern void input_sdl_init(); extern void input_sdl_handle(u32 port); +extern void input_sdl_rumble(u32 port, u16 pow_strong, u16 pow_weak); extern void sdl_window_create(); extern void sdl_window_set_text(const char* text); From f0c4fe6fdc1eab106fb94894ec60b74fa1def49c Mon Sep 17 00:00:00 2001 From: Marcel Szewczyk <marcel.szewczyk@gmail.com> Date: Fri, 18 Jan 2019 18:39:48 +0100 Subject: [PATCH 10/14] Additional improvements/fixes --- core/nullDC.cpp | 8 +--- core/rend/gles/gldraw.cpp | 6 +-- core/rend/gles/gles.cpp | 85 ++++++++++++++++++++++++++++++--------- 3 files changed, 70 insertions(+), 29 deletions(-) diff --git a/core/nullDC.cpp b/core/nullDC.cpp index c7e2c47448..95e5a3aefd 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -300,9 +300,9 @@ void LoadSettings() settings.rend.WideScreen = cfgLoadInt("config", "rend.WideScreen", 0); settings.rend.Clipping = cfgLoadInt("config", "rend.Clipping", 1); settings.rend. - VerticalResolution = cfgLoadInt("config", "rend.VerticalResolution", 100); + VerticalResolution = cfgLoadInt("config", "rend.ResolutionPercentage", 100); settings.rend. - HorizontalResolution = cfgLoadInt("config", "rend.HorizontalResolution", 100); + HorizontalResolution = cfgLoadInt("config", "rend.ResolutionPercentage", 100); settings.pvr.subdivide_transp = cfgLoadInt("config", "pvr.Subdivide", 0); @@ -370,10 +370,6 @@ void LoadCustom() settings.dynarec.safemode = cfgGameInt(reios_id,"Dynarec.safemode", settings.dynarec.safemode); settings.rend.ModifierVolumes = cfgGameInt(reios_id,"rend.ModifierVolumes", settings.rend.ModifierVolumes); settings.rend.Clipping = cfgGameInt(reios_id,"rend.Clipping", settings.rend.Clipping); - settings.rend. - VerticalResolution = cfgGameInt(reios_id, "rend.VerticalResolution", settings.rend.VerticalResolution); - settings.rend. - HorizontalResolution = cfgGameInt(reios_id, "rend.HorizontalResolution", settings.rend.HorizontalResolution); settings.pvr.subdivide_transp = cfgGameInt(reios_id,"pvr.Subdivide", settings.pvr.subdivide_transp); diff --git a/core/rend/gles/gldraw.cpp b/core/rend/gles/gldraw.cpp index 96788085cd..54a3df6b04 100644 --- a/core/rend/gles/gldraw.cpp +++ b/core/rend/gles/gldraw.cpp @@ -1219,9 +1219,9 @@ void DrawFullscreenQuad(float screenToNativeXScale, float screenToNativeYScale, u32 quadIndicesNumber = 6; GLint boundArrayBuffer = 0; GLint boundElementArrayBuffer = 0; - GLint vsPosition= glGetAttribLocation(gl.fullscreenQuadShader, "a_position"); - GLint vsTexcoord= glGetAttribLocation(gl.fullscreenQuadShader, "a_texcoord"); - GLint fsTexture = glGetUniformLocation(gl.fullscreenQuadShader, "s_texture"); + GLint vsPosition= glGetAttribLocation(gl.fullscreenQuadShader, "position"); + GLint vsTexcoord= glGetAttribLocation(gl.fullscreenQuadShader, "texture_coord"); + GLint fsTexture = glGetUniformLocation(gl.fullscreenQuadShader, "texture_data"); glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &boundArrayBuffer); glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &boundElementArrayBuffer); diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index 578538fdd8..54a02328fe 100755 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -421,27 +421,61 @@ void main() \n\ gl_FragColor=vtx_base*texture(tex,uv.st); \n\n\ }"; -const char * FullscreenQuadVertexShader = - "attribute vec3 a_position;\n\ - attribute vec2 a_texcoord;\n\ +const char* FullscreenQuadVertexShader = + "%s \n\ \n\ - varying vec2 v_texcoord; \n\ + #define TARGET_GL %s \n\ \n\ - void main()\n\ - {\n\ - v_texcoord = a_texcoord;\n\ - gl_Position = vec4(a_position, 1);\n\ + #define GLES2 0 \n\ + #define GLES3 1 \n\ + #define GL2 2 \n\ + #define GL3 3 \n\ + \n\ + #if TARGET_GL == GLES2 || TARGET_GL == GL2 \n\ + #define in attribute \n\ + #define out varying \n\ + #endif \n\ + \n\ + in vec3 position; \n\ + in vec2 texture_coord; \n\ + \n\ + out vec2 vs_texture_coord; \n\ + \n\ + void main() \n\ + { \n\ + vs_texture_coord = texture_coord; \n\ + gl_Position = vec4(position, 1); \n\ }"; -const char * FullscreenQuadFragmentShader = - "precision mediump float;\n\ - uniform sampler2D s_texture;\n\ +const char* FullscreenQuadFragmentShader = + "%s \n\ + \n\ + #define TARGET_GL %s \n\ \n\ - varying vec2 v_texcoord;\n\ + #define GLES2 0 \n\ + #define GLES3 1 \n\ + #define GL2 2 \n\ + #define GL3 3 \n\ \n\ - void main()\n\ - {\n\ - gl_FragColor = texture2D(s_texture, v_texcoord.st);\n\ + #if TARGET_GL == GLES2 || TARGET_GL == GLES3 \n\ + precision mediump float; \n\ + #endif \n\ + \n\ + #if TARGET_GL != GLES2 && TARGET_GL != GL2 \n\ + out vec4 FragColor; \n\ + #define gl_FragColor FragColor \n\ + #else \n\ + #define in varying \n\ + #define texture texture2D \n\ + #endif \n\ + \n\ + uniform sampler2D texture_data; \n\ + \n\ + in vec2 vs_texture_coord; \n\ + \n\ + void main() \n\ + { \n\ + gl_FragColor = texture(texture_data, vs_texture_coord.st); \n\ }"; gl_ctx gl; @@ -848,7 +882,15 @@ GLuint gl_CompileShader(const char* shader,GLuint type) *compile_log=0; glGetShaderInfoLog(rv, compile_log_len, &compile_log_len, compile_log); - printf("Shader: %s \n%s\n",result?"compiled!":"failed to compile",compile_log); + if (type == GL_VERTEX_SHADER) { + printf("Vertex shader: %s \n%s\n", result ? "compiled!" : "failed to compile", compile_log); + } + else if (type == GL_FRAGMENT_SHADER) { + printf("Fragment shader: %s \n%s\n", result ? "compiled!" : "failed to compile", compile_log); + } + else { + printf("Shader: %s \n%s\n", result ? "compiled!" : "failed to compile", compile_log); + } free(compile_log); } @@ -1100,9 +1142,10 @@ bool gl_create_resources() findGLVersion(); - char vshader[8192]; + const u32 maxShaderSize = 8192; + char vshader[maxShaderSize]; sprintf(vshader, VertexShaderSource, gl.glsl_version_header, gl.gl_version); - char fshader[8192]; + char fshader[maxShaderSize]; sprintf(fshader, ModifierVolumeShader, gl.glsl_version_header, gl.gl_version); gl.modvol_shader.program = gl_CompileAndLink(vshader, fshader, bindDefaultAttribLocations); @@ -1119,8 +1162,10 @@ bool gl_create_resources() gl.OSD_SHADER.depth_scale=glGetUniformLocation(gl.OSD_SHADER.program, "depth_scale"); glUniform1i(glGetUniformLocation(gl.OSD_SHADER.program, "tex"),0); //bind osd texture to slot 0 - if (!gl.fullscreenQuadShader) { - gl.fullscreenQuadShader = gl_CompileAndLink(FullscreenQuadVertexShader, FullscreenQuadFragmentShader); + if ((settings.rend.VerticalResolution != 100 || settings.rend.HorizontalResolution != 100) && !gl.fullscreenQuadShader) { + sprintf(vshader, FullscreenQuadVertexShader, gl.glsl_version_header, gl.gl_version); + sprintf(fshader, FullscreenQuadFragmentShader, gl.glsl_version_header, gl.gl_version); + gl.fullscreenQuadShader = gl_CompileAndLink(vshader, fshader); generateFullscreenQuadVertices(); } From c33c0cade8dbf8459b881500b1ebd9723e659073 Mon Sep 17 00:00:00 2001 From: Marcel Szewczyk <marcel.szewczyk@gmail.com> Date: Fri, 18 Jan 2019 18:42:10 +0100 Subject: [PATCH 11/14] LRR: Support for OpenGL 2 added --- core/rend/gles/gles.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index 54a02328fe..32917aaa08 100755 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -1646,8 +1646,12 @@ void fullscreenQuadCreateTemporaryFBO(float & screenToNativeXScale, float & scre glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width, screen_height); } #else - //OpenGL >= 3.0 is required - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, screen_width, screen_height); + if (!strcmp(gl.gl_version, "GL2")) { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, screen_width, screen_height); + } + else { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, screen_width, screen_height); + } #endif } @@ -1673,8 +1677,10 @@ void fullscreenQuadCreateTemporaryFBO(float & screenToNativeXScale, float & scre glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fullscreenQuad.framebufferRenderbuffer); } #else - //OpenGL >= 3.0 is required - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fullscreenQuad.framebufferRenderbuffer); + if (!strcmp(gl.gl_version, "GL3")) { + //OpenGL >= 3.0 is required + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fullscreenQuad.framebufferRenderbuffer); + } #endif GLuint uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); verify(uStatus == GL_FRAMEBUFFER_COMPLETE); From aa3475738a8c752b1691fc500458e3c60f20ad66 Mon Sep 17 00:00:00 2001 From: Marcel Szewczyk <marcel.szewczyk@gmail.com> Date: Sun, 20 Jan 2019 11:05:53 +0100 Subject: [PATCH 12/14] Revert "LRR: Support for OpenGL 2 added" This reverts commit c33c0cade8dbf8459b881500b1ebd9723e659073. --- core/rend/gles/gles.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index 32917aaa08..54a02328fe 100755 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -1646,12 +1646,8 @@ void fullscreenQuadCreateTemporaryFBO(float & screenToNativeXScale, float & scre glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width, screen_height); } #else - if (!strcmp(gl.gl_version, "GL2")) { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, screen_width, screen_height); - } - else { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, screen_width, screen_height); - } + //OpenGL >= 3.0 is required + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, screen_width, screen_height); #endif } @@ -1677,10 +1673,8 @@ void fullscreenQuadCreateTemporaryFBO(float & screenToNativeXScale, float & scre glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fullscreenQuad.framebufferRenderbuffer); } #else - if (!strcmp(gl.gl_version, "GL3")) { - //OpenGL >= 3.0 is required - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fullscreenQuad.framebufferRenderbuffer); - } + //OpenGL >= 3.0 is required + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fullscreenQuad.framebufferRenderbuffer); #endif GLuint uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); verify(uStatus == GL_FRAMEBUFFER_COMPLETE); From 377fb6ace0a258c9f2356890628b47103b82355d Mon Sep 17 00:00:00 2001 From: Marcel Szewczyk <marcel.szewczyk@gmail.com> Date: Fri, 25 Jan 2019 16:43:46 +0100 Subject: [PATCH 13/14] rend.ResolutionPercentage acceptable values are now from 1 to 100; naming fix --- core/rend/gles/gles.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index 54a02328fe..15fae4dace 100755 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -1630,7 +1630,8 @@ void OSD_DRAW() #endif } -void fullscreenQuadCreateTemporaryFBO(float & screenToNativeXScale, float & screenToNativeY) { +void fullscreenQuadCreateTemporaryFBO(float & screenToNativeXScale, float & screenToNativeYScale) +{ // Generate and bind a render buffer which will become a depth buffer if (!fullscreenQuad.framebufferRenderbuffer) { glGenRenderbuffers(1, &fullscreenQuad.framebufferRenderbuffer); @@ -1683,7 +1684,7 @@ void fullscreenQuadCreateTemporaryFBO(float & screenToNativeXScale, float & scre glBindFramebuffer(GL_FRAMEBUFFER, fullscreenQuad.framebuffer); } - glViewport(0, 0, screen_width * screenToNativeXScale, screen_height * screenToNativeY); + glViewport(0, 0, screen_width * screenToNativeXScale, screen_height * screenToNativeYScale); } bool ProcessFrame(TA_context* ctx) @@ -1808,8 +1809,16 @@ bool RenderFrame() //these should be adjusted based on the current PVR scaling etc params float dc_width = 640; float dc_height = 480; - float screenToNativeXScale = settings.rend.HorizontalResolution / 100.0f; - float screenToNativeYScale = settings.rend.VerticalResolution / 100.0f; + float screenToNativeXScale = 1.0f; + float screenToNativeYScale = 1.0f; + + if (settings.rend.HorizontalResolution >= 1 && settings.rend.HorizontalResolution < 100) { + screenToNativeXScale = settings.rend.HorizontalResolution / 100.0f; + } + + if (settings.rend.VerticalResolution >= 1 && settings.rend.VerticalResolution < 100) { + screenToNativeYScale = settings.rend.VerticalResolution / 100.0f; + } if (!is_rtt) { From d558f5182a44b1359247afe1ac9e38806f2d5025 Mon Sep 17 00:00:00 2001 From: Marcel Szewczyk <5397997+mar753@users.noreply.github.com> Date: Thu, 31 Jan 2019 21:13:49 +0100 Subject: [PATCH 14/14] German translation added --- .../android-studio/reicast/src/main/res/values-de/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shell/android-studio/reicast/src/main/res/values-de/strings.xml b/shell/android-studio/reicast/src/main/res/values-de/strings.xml index 11b824116a..aaaf4bb284 100644 --- a/shell/android-studio/reicast/src/main/res/values-de/strings.xml +++ b/shell/android-studio/reicast/src/main/res/values-de/strings.xml @@ -45,6 +45,9 @@ <string name="select_software">Softwarerendering erzwingen</string> <string name="select_sound">Emulator-Sound deaktivieren</string> <string name="select_depth">Rendering-Tiefe</string> + <string name="resolution">Auflösung (niedriger = schneller)</string> + <string name="resolution_vertical">Vertikal</string> + <string name="resolution_horizontal">Horizontal</string> <string name="games_listing">Verfügbare Dreamcast-Spiele</string>