diff --git a/CMakeLists.txt b/CMakeLists.txt index b1f98c2577..785d38b7ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,7 @@ option(BLACKBERRY "Set to ON if targeting a Blackberry device" ${BLACKBERRY}) option(IOS "Set to ON if targeting an iOS device" ${IOS}) option(USING_GLES2 "Set to ON if target device uses OpenGL ES 2.0" ${USING_GLES2}) option(HEADLESS "Set to OFF to not generate the PPSSPPHeadless target" ${HEADLESS}) +option(DEBUG "Set to ON to enable full debug logging" ${DEBUG}) if(ANDROID) if(NOT ANDROID_ABI) @@ -101,12 +102,16 @@ if (USING_GLES2) add_definitions(-DUSING_GLES2) endif() +if(DEBUG) + add_definitions(-D_DEBUG) +endif() + if(NOT MSVC) # Disable some warnings - add_definitions(-Wno-psabi) add_definitions(-Wno-multichar) add_definitions(-fno-strict-aliasing) if(NOT APPLE) + add_definitions(-Wno-psabi) add_definitions(-D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED -D__BSD_VISIBLE=1) add_definitions(-D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64) endif() diff --git a/Core/Config.cpp b/Core/Config.cpp index aa8fb39afa..eb09dece92 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -48,7 +48,7 @@ void CConfig::Load(const char *iniFileName) general->Get("ConfirmOnQuit", &bConfirmOnQuit, false); general->Get("IgnoreBadMemAccess", &bIgnoreBadMemAccess, true); general->Get("CurrentDirectory", ¤tDirectory, ""); - + general->Get("ShowDebuggerOnLoad", &bShowDebuggerOnLoad, false); IniFile::Section *cpu = iniFile.GetOrCreateSection("CPU"); cpu->Get("Core", &iCpuCore, 0); @@ -63,6 +63,7 @@ void CConfig::Load(const char *iniFileName) IniFile::Section *control = iniFile.GetOrCreateSection("Control"); control->Get("ShowStick", &bShowAnalogStick, false); + control->Get("ShowTouchControls", &bShowTouchControls, true); } void CConfig::Save() @@ -79,7 +80,7 @@ void CConfig::Save() general->Set("ConfirmOnQuit", bConfirmOnQuit); general->Set("IgnoreBadMemAccess", bIgnoreBadMemAccess); general->Set("CurrentDirectory", currentDirectory); - + general->Set("ShowDebuggerOnLoad", bShowDebuggerOnLoad); IniFile::Section *cpu = iniFile.GetOrCreateSection("CPU"); cpu->Set("Core", iCpuCore); @@ -94,6 +95,7 @@ void CConfig::Save() IniFile::Section *control = iniFile.GetOrCreateSection("Control"); control->Set("ShowStick", bShowAnalogStick); + control->Set("ShowTouchControls", bShowTouchControls); iniFile.Save(iniFilename_.c_str()); NOTICE_LOG(LOADER, "Config saved: %s", iniFilename_.c_str()); diff --git a/Core/Config.h b/Core/Config.h index f7add3be19..f483e47d6f 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -44,6 +44,8 @@ public: bool bDisplayFramebuffer; bool bBufferedRendering; + bool bShowTouchControls; + bool bShowDebuggerOnLoad; bool bShowAnalogStick; bool bShowFPSCounter; bool bShowDebugStats; @@ -58,6 +60,5 @@ private: std::string iniFilename_; }; - extern SState g_State; extern CConfig g_Config; diff --git a/Core/HLE/sceAudio.cpp b/Core/HLE/sceAudio.cpp index 6b7cbcc071..35f76a04e1 100644 --- a/Core/HLE/sceAudio.cpp +++ b/Core/HLE/sceAudio.cpp @@ -323,7 +323,7 @@ u32 sceAudioOutput2Reserve(u32 sampleCount) void sceAudioOutput2OutputBlocking(u32 vol, u32 dataPtr) { - WARN_LOG(HLE,"FAKE sceAudioOutput2OutputBlocking(%i, %08x)", vol, dataPtr); + DEBUG_LOG(HLE,"FAKE sceAudioOutput2OutputBlocking(%i, %08x)", vol, dataPtr); chans[0].leftVolume = vol; chans[0].rightVolume = vol; chans[0].sampleAddress = dataPtr; diff --git a/Core/HLE/sceRtc.cpp b/Core/HLE/sceRtc.cpp index 7d9067a538..c63094b2b7 100644 --- a/Core/HLE/sceRtc.cpp +++ b/Core/HLE/sceRtc.cpp @@ -618,18 +618,30 @@ int sceRtcTickAddMonths(u32 destTickPtr, u32 srcTickPtr, int numMonths) { if (Memory::IsValidAddress(destTickPtr) && Memory::IsValidAddress(srcTickPtr)) { - s64 srcTick = (s64)Memory::Read_U64(srcTickPtr); + u64 srcTick = Memory::Read_U64(srcTickPtr); - // slightly bodgy but we need to add months to a pt and then convert to ticks (untested and broken) + // slightly bodgy but we need to add months to a pt and then convert to ticks ScePspDateTime pt; - - int years = numMonths /12; - int realmonths = numMonths % 12; memset(&pt, 0, sizeof(pt)); - pt.year = years; - pt.month = realmonths; - srcTick +=__RtcPspTimeToTicks(pt); - + if (numMonths < 0) + { + numMonths = (numMonths^0xFFFFFFFF)+1; + int years = numMonths /12; + int realmonths = numMonths % 12; + + pt.year = years; + pt.month = realmonths; + srcTick -=__RtcPspTimeToTicks(pt); + } + else + { + int years = numMonths /12; + int realmonths = numMonths % 12; + + pt.year = years; + pt.month = realmonths; + srcTick +=__RtcPspTimeToTicks(pt); + } Memory::Write_U64(srcTick, destTickPtr); } diff --git a/Core/HLE/sceSas.cpp b/Core/HLE/sceSas.cpp index 7f47ef87bf..1c2ae9ce8b 100644 --- a/Core/HLE/sceSas.cpp +++ b/Core/HLE/sceSas.cpp @@ -361,6 +361,19 @@ void sceSasRevParam() RETURN(0); } +u32 sceSasGetPauseFlag() +{ + u32 PauseFlag = 0; + for (int i = 0; i < sas.maxVoices; i++) { + if (!sas.voices[i].playing) + PauseFlag |= 1 << i; + } + DEBUG_LOG(HLE,"%08x=sceSasGetPauseFlag()", PauseFlag); + return PauseFlag; +} + + + void sceSasRevEVOL() { u32 core = PARAM(0); @@ -410,7 +423,7 @@ const HLEFunction sceSasCore[] = {0xd5a229c9, sceSasRevEVOL, "__sceSasRevEVOL"}, // (int sasCore, int leftVol, int rightVol) // effect volume {0x33d4ab37, sceSasRevType, "__sceSasRevType"}, // (int sasCore, int type) {0x267a6dd2, sceSasRevParam, "__sceSasRevParam"}, // (int sasCore, int delay, int feedback) - {0x2c8e6ab3, 0, "__sceSasGetPauseFlag"}, // int sasCore + {0x2c8e6ab3, WrapU_V, "__sceSasGetPauseFlag"}, // int sasCore {0x787d04d5, 0, "__sceSasSetPause"}, {0xa232cbe6, 0, "__sceSasSetTriangularWave"}, // (int sasCore, int voice, int unknown) {0xd5ebbbcd, 0, "__sceSasSetSteepWave"}, // (int sasCore, int voice, int unknown) // square wave? diff --git a/GPU/GLES/DisplayListInterpreter.cpp b/GPU/GLES/DisplayListInterpreter.cpp index efcad63c1f..1f84c5ed1f 100644 --- a/GPU/GLES/DisplayListInterpreter.cpp +++ b/GPU/GLES/DisplayListInterpreter.cpp @@ -175,7 +175,7 @@ void GLES_GPU::SetRenderFrameBuffer() int drawing_height = ((gstate.region2 >> 10) & 0x3FF) + 1; int fmt = gstate.framebufpixformat & 3; - + // Find a matching framebuffer VirtualFramebuffer *vfb = 0; for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter) @@ -189,7 +189,7 @@ void GLES_GPU::SetRenderFrameBuffer() break; } } - + // None found? Create one. if (!vfb) { vfb = new VirtualFramebuffer; @@ -442,7 +442,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) case GE_CMD_RET: //TODO : debug! { - u32 target = dcontext.pc & 0xF0000000 | (stack[--stackptr] & 0x0FFFFFFF); + u32 target = (dcontext.pc & 0xF0000000) | (stack[--stackptr] & 0x0FFFFFFF); DEBUG_LOG(G3D,"DL CMD RET - from %08x to %08x", dcontext.pc, target); dcontext.pc = target - 4; } @@ -571,38 +571,38 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) break; case GE_CMD_FOGENABLE: - DEBUG_LOG(G3D, "DL Fog Enable: %i", gstate.fogEnable); + DEBUG_LOG(G3D, "DL Fog Enable: %i", data); break; case GE_CMD_DITHERENABLE: - DEBUG_LOG(G3D, "DL Dither Enable: %i", gstate.ditherEnable); + DEBUG_LOG(G3D, "DL Dither Enable: %i", data); break; case GE_CMD_OFFSETX: - DEBUG_LOG(G3D, "DL Offset X: %i", gstate.offsetx); + DEBUG_LOG(G3D, "DL Offset X: %i", data); break; case GE_CMD_OFFSETY: - DEBUG_LOG(G3D, "DL Offset Y: %i", gstate.offsety); + DEBUG_LOG(G3D, "DL Offset Y: %i", data); break; - case GE_CMD_TEXSCALEU: - gstate_c.uScale = getFloat24(data); + case GE_CMD_TEXSCALEU: + gstate_c.uScale = getFloat24(data); DEBUG_LOG(G3D, "DL Texture U Scale: %f", gstate_c.uScale); break; - case GE_CMD_TEXSCALEV: - gstate_c.vScale = getFloat24(data); + case GE_CMD_TEXSCALEV: + gstate_c.vScale = getFloat24(data); DEBUG_LOG(G3D, "DL Texture V Scale: %f", gstate_c.vScale); break; - case GE_CMD_TEXOFFSETU: - gstate_c.uOff = getFloat24(data); + case GE_CMD_TEXOFFSETU: + gstate_c.uOff = getFloat24(data); DEBUG_LOG(G3D, "DL Texture U Offset: %f", gstate_c.uOff); break; - case GE_CMD_TEXOFFSETV: - gstate_c.vOff = getFloat24(data); + case GE_CMD_TEXOFFSETV: + gstate_c.vOff = getFloat24(data); DEBUG_LOG(G3D, "DL Texture V Offset: %f", gstate_c.vOff); break; @@ -998,7 +998,9 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) DEBUG_LOG(G3D,"DL TexFilter min: %i mag: %i", min, mag); } break; - + case GE_CMD_TEXENVCOLOR: + DEBUG_LOG(G3D,"DL TexEnvColor %06x", data); + break; case GE_CMD_TEXMODE: DEBUG_LOG(G3D,"DL TexMode %08x", data); break; @@ -1044,7 +1046,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) gstate_c.morphWeights[index] = weight; } break; - + case GE_CMD_DITH0: case GE_CMD_DITH1: case GE_CMD_DITH2: @@ -1053,12 +1055,12 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) break; case GE_CMD_WORLDMATRIXNUMBER: - DEBUG_LOG(G3D,"DL World matrix # %i", data & 0xF); + DEBUG_LOG(G3D,"DL World # %i", data & 0xF); gstate.worldmtxnum &= 0xFF00000F; break; case GE_CMD_WORLDMATRIXDATA: - DEBUG_LOG(G3D,"DL World matrix data # %f", getFloat24(data)); + DEBUG_LOG(G3D,"DL World data # %f", getFloat24(data)); { int num = gstate.worldmtxnum & 0xF; if (num < 12) @@ -1068,12 +1070,12 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) break; case GE_CMD_VIEWMATRIXNUMBER: - DEBUG_LOG(G3D,"DL VIEW matrix # %i", data & 0xF); + DEBUG_LOG(G3D,"DL VIEW # %i", data & 0xF); gstate.viewmtxnum &= 0xFF00000F; break; case GE_CMD_VIEWMATRIXDATA: - DEBUG_LOG(G3D,"DL VIEW matrix data # %f", getFloat24(data)); + DEBUG_LOG(G3D,"DL VIEW data # %f", getFloat24(data)); { int num = gstate.viewmtxnum & 0xF; if (num < 12) @@ -1083,14 +1085,14 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) break; case GE_CMD_PROJMATRIXNUMBER: - DEBUG_LOG(G3D,"DL PROJECTION matrix # %i", data & 0xF); + DEBUG_LOG(G3D,"DL PROJECTION # %i", data & 0xF); gstate.projmtxnum &= 0xFF00000F; break; case GE_CMD_PROJMATRIXDATA: DEBUG_LOG(G3D,"DL PROJECTION matrix data # %f", getFloat24(data)); { - int num = gstate.projmtxnum & 0xF; + int num = gstate.projmtxnum & 0xF; gstate.projMatrix[num++] = getFloat24(data); gstate.projmtxnum = (gstate.projmtxnum & 0xFF000000) | (num & 0xF); } @@ -1098,12 +1100,12 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) break; case GE_CMD_TGENMATRIXNUMBER: - DEBUG_LOG(G3D,"DL TGEN matrix # %i", data & 0xF); + DEBUG_LOG(G3D,"DL TGEN # %i", data & 0xF); gstate.texmtxnum &= 0xFF00000F; break; case GE_CMD_TGENMATRIXDATA: - DEBUG_LOG(G3D,"DL TGEN matrix data # %f", getFloat24(data)); + DEBUG_LOG(G3D,"DL TGEN data # %f", getFloat24(data)); { int num = gstate.texmtxnum & 0xF; if (num < 12) @@ -1113,12 +1115,12 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) break; case GE_CMD_BONEMATRIXNUMBER: - DEBUG_LOG(G3D,"DL BONE matrix #%i", data); + DEBUG_LOG(G3D,"DL BONE #%i", data); gstate.boneMatrixNumber &= 0xFF00007F; break; case GE_CMD_BONEMATRIXDATA: - DEBUG_LOG(G3D,"DL BONE matrix data #%i %f", gstate.boneMatrixNumber & 0x7f, getFloat24(data)); + DEBUG_LOG(G3D,"DL BONE data #%i %f", gstate.boneMatrixNumber & 0x7f, getFloat24(data)); { int num = gstate.boneMatrixNumber & 0x7F; if (num < 96) { diff --git a/GPU/GLES/FragmentShaderGenerator.cpp b/GPU/GLES/FragmentShaderGenerator.cpp index 6dbbb39fa8..e42e96e2b6 100644 --- a/GPU/GLES/FragmentShaderGenerator.cpp +++ b/GPU/GLES/FragmentShaderGenerator.cpp @@ -27,7 +27,6 @@ #endif #endif - #include "FragmentShaderGenerator.h" #include "../ge_constants.h" #include "../GPUState.h" @@ -76,7 +75,9 @@ char *GenerateFragmentShader() int lmode = gstate.lmode & 1; - if (gstate.textureMapEnable & 1) + int doTexture = (gstate.textureMapEnable & 1) && !(gstate.clearmode & 1); + + if (doTexture) WRITE(p, "uniform sampler2D tex;\n"); if (gstate.alphaTestEnable & 1) WRITE(p, "uniform vec4 u_alpharef;\n"); @@ -88,7 +89,8 @@ char *GenerateFragmentShader() WRITE(p, "varying vec4 v_color0;\n"); if (lmode) WRITE(p, "varying vec4 v_color1;\n"); - WRITE(p, "varying vec2 v_texcoord;\n"); + if (doTexture) + WRITE(p, "varying vec2 v_texcoord;\n"); if (gstate.isFogEnabled()) WRITE(p, "varying float v_depth;\n"); @@ -97,6 +99,7 @@ char *GenerateFragmentShader() if (gstate.clearmode & 1) { + // Clear mode does not allow any fancy shading. WRITE(p, " v = v_color0;\n"); } else @@ -155,7 +158,7 @@ char *GenerateFragmentShader() if (gstate.texfunc & 0x10000) { WRITE(p, " v = v * vec4(2.0, 2.0, 2.0, 1.0);"); } - + if (gstate.alphaTestEnable & 1) { int alphaTestFunc = gstate.alphatest & 7; const char *alphaTestFuncs[] = { "#", "#", " == ", " != ", " < ", " <= ", " > ", " >= " }; // never/always don't make sense @@ -168,7 +171,6 @@ char *GenerateFragmentShader() // WRITE(p, " v = mix(v, u_fogcolor, u_fogcoef.x + u_fogcoef.y * v_depth;\n"); // WRITE(p, " v.x = v_depth;\n"); } - // Fogging should be added here - and disabled during clear mode } WRITE(p, " gl_FragColor = v;\n"); diff --git a/GPU/GLES/ShaderManager.cpp b/GPU/GLES/ShaderManager.cpp index 0f004653c2..857968560b 100644 --- a/GPU/GLES/ShaderManager.cpp +++ b/GPU/GLES/ShaderManager.cpp @@ -25,9 +25,7 @@ #include "TransformPipeline.h" Shader::Shader(const char *code, uint32_t shaderType) { -#ifdef _DEBUG source_ = code; -#endif #ifdef _WIN32 // OutputDebugString(code); #endif @@ -46,7 +44,7 @@ Shader::Shader(const char *code, uint32_t shaderType) { ERROR_LOG(G3D, "Info log: %s\n", infoLog); ERROR_LOG(G3D, "Shader source:\n%s\n", (const char *)code); } else { - //NOTICE_LOG(G3D, "Compiled shader:\n%s\n", (const char *)code); + DEBUG_LOG(G3D, "Compiled shader:\n%s\n", (const char *)code); } } @@ -66,33 +64,33 @@ LinkedShader::LinkedShader(Shader *vs, Shader *fs) char* buf = new char[bufLength]; glGetProgramInfoLog(program, bufLength, NULL, buf); ERROR_LOG(G3D, "Could not link program:\n %s", buf); + ERROR_LOG(G3D, "VS:\n%s", vs->source().c_str()); + ERROR_LOG(G3D, "FS:\n%s", fs->source().c_str()); delete [] buf; // we're dead! - - //_dbg_assert_msg_(HLE,0,"Could not link program"); } return; } - NOTICE_LOG(G3D, "Linked shader!"); + INFO_LOG(G3D, "Linked shader: vs %i fs %i", (int)vs->shader, (int)fs->shader); - u_tex = glGetUniformLocation(program, "tex"); - u_proj = glGetUniformLocation(program, "u_proj"); + u_tex = glGetUniformLocation(program, "tex"); + u_proj = glGetUniformLocation(program, "u_proj"); u_proj_through = glGetUniformLocation(program, "u_proj_through"); u_texenv = glGetUniformLocation(program, "u_texenv"); u_fogcolor = glGetUniformLocation(program, "u_fogcolor"); u_fogcoef = glGetUniformLocation(program, "u_fogcoef"); u_alpharef = glGetUniformLocation(program, "u_alpharef"); - a_position = glGetAttribLocation(program, "a_position"); - a_color0 = glGetAttribLocation(program, "a_color0"); - a_color1 = glGetAttribLocation(program, "a_color1"); - a_texcoord = glGetAttribLocation(program, "a_texcoord"); + a_position = glGetAttribLocation(program, "a_position"); + a_color0 = glGetAttribLocation(program, "a_color0"); + a_color1 = glGetAttribLocation(program, "a_color1"); + a_texcoord = glGetAttribLocation(program, "a_texcoord"); glUseProgram(program); // Default uniform values glUniform1i(u_tex, 0); // The rest, use the "dirty" mechanism. - dirtyUniforms = DIRTY_PROJMATRIX | DIRTY_TEXENV | DIRTY_ALPHAREF; + dirtyUniforms = DIRTY_PROJMATRIX | DIRTY_PROJTHROUGHMATRIX | DIRTY_TEXENV | DIRTY_ALPHAREF; } LinkedShader::~LinkedShader() { @@ -100,7 +98,7 @@ LinkedShader::~LinkedShader() { } void LinkedShader::use() { - glUseProgram(program); + glUseProgram(program); glUniform1i(u_tex, 0); // Update any dirty uniforms before we draw if (u_proj != -1 && (dirtyUniforms & DIRTY_PROJMATRIX)) { @@ -175,7 +173,7 @@ void ShaderManager::DirtyShader() } -LinkedShader *ShaderManager::ApplyShader() +LinkedShader *ShaderManager::ApplyShader(int prim) { if (globalDirty) { // Deferred dirtying! Let's see if we can make this even more clever later. @@ -187,7 +185,7 @@ LinkedShader *ShaderManager::ApplyShader() VertexShaderID VSID; FragmentShaderID FSID; - ComputeVertexShaderID(&VSID); + ComputeVertexShaderID(&VSID, prim); ComputeFragmentShaderID(&FSID); // Bail quickly in the no-op case. TODO: why does it cause trouble? @@ -206,7 +204,7 @@ LinkedShader *ShaderManager::ApplyShader() } else { vs = vsIter->second; } - + FSCache::iterator fsIter = fsCache.find(FSID); Shader *fs; if (fsIter == fsCache.end()) { diff --git a/GPU/GLES/ShaderManager.h b/GPU/GLES/ShaderManager.h index 080b5331e3..33c5b308dc 100644 --- a/GPU/GLES/ShaderManager.h +++ b/GPU/GLES/ShaderManager.h @@ -33,7 +33,6 @@ struct LinkedShader void use(); uint32_t program; - u32 dirtyUniforms; // Pre-fetched attrs and uniforms @@ -53,8 +52,13 @@ struct LinkedShader int u_alpharef; int u_fogcolor; int u_fogcoef; + + // Lighting + int u_ambientcolor; + int u_light[4]; // each light consist of vec4[3] }; +// Will reach 32 bits soon :P enum { DIRTY_PROJMATRIX = (1 << 0), @@ -63,8 +67,29 @@ enum DIRTY_FOGCOEF = (1 << 3), DIRTY_TEXENV = (1 << 4), DIRTY_ALPHAREF = (1 << 5), + DIRTY_COLORREF = (1 << 6), - DIRTY_ALL = (1 << 6) - 1 + DIRTY_LIGHT0 = (1 << 12), + DIRTY_LIGHT1 = (1 << 13), + DIRTY_LIGHT2 = (1 << 14), + DIRTY_LIGHT3 = (1 << 15), + + DIRTY_GLOBALAMBIENT = (1 << 16), + DIRTY_MATERIAL = (1 << 17), // let's set all 4 together (emissive ambient diffuse specular). We hide specular coef in specular.a + DIRTY_UVSCALEOFFSET = (1 << 18), // this will be dirtied ALL THE TIME... maybe we'll need to do "last value with this shader compares" + + DIRTY_VIEWMATRIX = (1 << 22), // Maybe we'll fold this into projmatrix eventually + DIRTY_TEXMATRIX = (1 << 23), + DIRTY_BONEMATRIX0 = (1 << 24), + DIRTY_BONEMATRIX1 = (1 << 25), + DIRTY_BONEMATRIX2 = (1 << 26), + DIRTY_BONEMATRIX3 = (1 << 27), + DIRTY_BONEMATRIX4 = (1 << 28), + DIRTY_BONEMATRIX5 = (1 << 29), + DIRTY_BONEMATRIX6 = (1 << 30), + DIRTY_BONEMATRIX7 = (1 << 31), + + DIRTY_ALL = 0xFFFFFFFF }; // Real public interface @@ -73,6 +98,7 @@ struct Shader { Shader(const char *code, uint32_t shaderType); uint32_t shader; + const std::string &source() const { return source_; } private: std::string source_; }; @@ -84,7 +110,7 @@ public: ShaderManager() : globalDirty(0xFFFFFFFF) {} void ClearCache(bool deleteThem); // TODO: deleteThem currently not respected - LinkedShader *ApplyShader(); + LinkedShader *ApplyShader(int prim); void DirtyShader(); void DirtyUniform(u32 what); diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index a1c9ad31fa..31071a23b6 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -119,9 +119,9 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[ specular = ∈ else specular = &materialSpecular; - + Color4 lightSum0 = globalAmbient * *ambient + materialEmissive; - Color4 lightSum1(0,0,0,0); + Color4 lightSum1(0, 0, 0, 0); // Try lights.elf - there's something wrong with the lighting @@ -131,8 +131,8 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[ if ((gstate.lightEnable[l] & 1) == 0 && !doShadeMapping_) continue; - GELightComputation comp = (GELightComputation)(gstate.ltype[l]&3); - GELightType type = (GELightType)((gstate.ltype[l]>>8)&3); + GELightComputation comp = (GELightComputation)(gstate.ltype[l] & 3); + GELightType type = (GELightType)((gstate.ltype[l] >> 8) & 3); Vec3 toLight; if (type == GE_LIGHTTYPE_DIRECTIONAL) @@ -146,7 +146,7 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[ float lightScale = 1.0f; if (type != GE_LIGHTTYPE_DIRECTIONAL) { - float distance = toLight.Normalize(); + float distance = toLight.Normalize(); lightScale = 1.0f / (gstate_c.lightatt[l][0] + gstate_c.lightatt[l][1]*distance + gstate_c.lightatt[l][2]*distance*distance); if (lightScale > 1.0f) lightScale = 1.0f; } @@ -159,12 +159,12 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[ if (poweredDiffuse) dot = powf(dot, specCoef_); - Color4 diff = (gstate_c.lightColor[1][l] * *diffuse) * (dot * lightScale); + Color4 diff = (gstate_c.lightColor[1][l] * *diffuse) * (dot * lightScale); // Real PSP specular Vec3 toViewer(0,0,1); // Better specular - //Vec3 toViewer = (viewer - pos).Normalized(); + // Vec3 toViewer = (viewer - pos).Normalized(); if (doSpecular) { @@ -176,7 +176,7 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[ if (dot >= 0) { lightSum1 += (gstate_c.lightColor[2][l] * *specular * (powf(dot, specCoef_)*lightScale)); - } + } } dots[l] = dot; if (gstate.lightEnable[l] & 1) @@ -203,7 +203,11 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte VertexDecoder dec; dec.SetVertexType(gstate.vertType); dec.DecodeVerts(decoded, verts, inds, prim, vertexCount, &indexLowerBound, &indexUpperBound); - +#if 0 + for (int i = indexLowerBound; i <= indexUpperBound; i++) { + PrintDecodedVertex(decoded[i], gstate.vertType); + } +#endif bool useTexCoord = false; // Check if anything needs updating @@ -217,14 +221,14 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte } gpuStats.numDrawCalls++; gpuStats.numVertsTransformed += vertexCount; - + if (bytesRead) *bytesRead = vertexCount * dec.VertexSize(); bool throughmode = (gstate.vertType & GE_VTYPE_THROUGH_MASK) != 0; // Then, transform and draw in one big swoop (urgh!) // need to move this to the shader. - + // We're gonna have to keep software transforming RECTANGLES, unless we use a geom shader which we can't on OpenGL ES 2.0. // Usually, though, these primitives don't use lighting etc so it's no biggie performance wise, but it would be nice to get rid of // this code. @@ -322,7 +326,7 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte float litColor0[4]; float litColor1[4]; lighter.Light(litColor0, litColor1, unlitColor, out, norm, dots); - + if (gstate.lightingEnable & 1) { // TODO: don't ignore gstate.lmode - we should send two colors in that case @@ -459,7 +463,7 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte if (indexType == GE_VTYPE_IDX_8BIT) { index = ((u8*)inds)[i]; - } + } else if (indexType == GE_VTYPE_IDX_16BIT) { index = ((u16*)inds)[i]; @@ -480,7 +484,7 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte // We have to turn the rectangle into two triangles, so 6 points. Sigh. // TODO: there's supposed to be extra magic here to rotate the UV coordinates depending on if upside down etc. - + // bottom right *trans = transVtx; trans++; @@ -606,17 +610,19 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte glstate.depthTest.set(wantDepthTest); if(wantDepthTest) { // Force GL_ALWAYS if mode clear - u8 depthTestFunc = gstate.isModeClear() ? 1 : gstate.getDepthTestFunc(); + int depthTestFunc = gstate.isModeClear() ? 1 : gstate.getDepthTestFunc(); glstate.depthFunc.set(ztests[depthTestFunc]); } bool wantDepthWrite = gstate.isModeClear() || gstate.isDepthWriteEnabled(); glstate.depthWrite.set(wantDepthWrite ? GL_TRUE : GL_FALSE); - glstate.depthRange.set(gstate_c.zOff - gstate_c.zScale, gstate_c.zOff + gstate_c.zScale); + float depthRangeMin = gstate_c.zOff - gstate_c.zScale; + float depthRangeMax = gstate_c.zOff + gstate_c.zScale; + glstate.depthRange.set(depthRangeMin, depthRangeMax); UpdateViewportAndProjection(); - LinkedShader *program = shaderManager_->ApplyShader(); + LinkedShader *program = shaderManager_->ApplyShader(prim); // TODO: Make a cache for glEnableVertexAttribArray and glVertexAttribPtr states, these spam the gDebugger log. glEnableVertexAttribArray(program->a_position); @@ -625,7 +631,7 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte if (program->a_color1 != -1) glEnableVertexAttribArray(program->a_color1); const int vertexSize = sizeof(transformed[0]); glVertexAttribPointer(program->a_position, 3, GL_FLOAT, GL_FALSE, vertexSize, drawBuffer); - if (useTexCoord && program->a_texcoord != -1) glVertexAttribPointer(program->a_texcoord, 2, GL_FLOAT, GL_FALSE, vertexSize, ((uint8_t*)drawBuffer) + 3 * 4); + if (useTexCoord && program->a_texcoord != -1) glVertexAttribPointer(program->a_texcoord, 2, GL_FLOAT, GL_FALSE, vertexSize, ((uint8_t*)drawBuffer) + 3 * 4); if (program->a_color0 != -1) glVertexAttribPointer(program->a_color0, 4, GL_FLOAT, GL_FALSE, vertexSize, ((uint8_t*)drawBuffer) + 5 * 4); if (program->a_color1 != -1) glVertexAttribPointer(program->a_color1, 4, GL_FLOAT, GL_FALSE, vertexSize, ((uint8_t*)drawBuffer) + 9 * 4); // NOTICE_LOG(G3D,"DrawPrimitive: %i", numTrans); @@ -643,7 +649,7 @@ void GLES_GPU::TransformAndDrawPrim(void *verts, void *inds, int prim, int verte void GLES_GPU::UpdateViewportAndProjection() { bool throughmode = (gstate.vertType & GE_VTYPE_THROUGH_MASK) != 0; - + // We can probably use these to simply set scissors? Maybe we need to offset by regionX1/Y1 int regionX1 = gstate.region1 & 0x3FF; int regionY1 = (gstate.region1 >> 10) & 0x3FF; @@ -654,8 +660,8 @@ void GLES_GPU::UpdateViewportAndProjection() float offsetY = (float)(gstate.offsety & 0xFFFF) / 16.0f; if (throughmode) { - return; // No viewport transform here. Let's experiment with using region. + return; glViewport((0 + regionX1) * renderWidthFactor_, (0 - regionY1) * renderHeightFactor_, (regionX2 - regionX1) * renderWidthFactor_, (regionY2 - regionY1) * renderHeightFactor_); } else { // These we can turn into a glViewport call, offset by offsetX and offsetY. Math after. @@ -693,8 +699,8 @@ void GLES_GPU::UpdateViewportAndProjection() // Flip vpY0 to match the OpenGL coordinate system. vpY0 = renderHeight_ - (vpY0 + vpHeight); - glViewport(vpX0, vpY0, vpWidth, vpHeight); + glViewport(vpX0, vpY0, vpWidth, vpHeight); // Sadly, as glViewport takes integers, we will not be able to support sub pixel offsets this way. But meh. shaderManager_->DirtyUniform(DIRTY_PROJMATRIX); } -} \ No newline at end of file +} diff --git a/GPU/GLES/VertexDecoder.cpp b/GPU/GLES/VertexDecoder.cpp index 5f7acbb29c..33f3281865 100644 --- a/GPU/GLES/VertexDecoder.cpp +++ b/GPU/GLES/VertexDecoder.cpp @@ -22,6 +22,15 @@ #include "VertexDecoder.h" +void PrintDecodedVertex(const DecodedVertex &vtx, u32 vtype) +{ + if (vtype & GE_VTYPE_NRM_MASK) printf("N: %f %f %f\n", vtx.normal[0], vtx.normal[1], vtx.normal[2]); + if (vtype & GE_VTYPE_TC_MASK) printf("TC: %f %f\n", vtx.uv[0], vtx.uv[1]); + if (vtype & GE_VTYPE_COL_MASK) printf("C: %02x %02x %02x %02x\n", vtx.color[0], vtx.color[1], vtx.color[2], vtx.color[3]); + if (vtype & GE_VTYPE_WEIGHT_MASK) printf("W: TODO\n"); + printf("P: %f %f %f\n", vtx.pos[0], vtx.pos[1], vtx.pos[2]); +} + const int tcsize[4] = {0,2,4,8}, tcalign[4] = {0,1,2,4}; const int colsize[8] = {0,0,0,0,2,2,2,4}, colalign[8] = {0,0,0,0,2,2,2,4}; const int nrmsize[4] = {0,3,6,12}, nrmalign[4] = {0,1,2,4}; @@ -30,7 +39,7 @@ const int wtsize[4] = {0,1,2,4}, wtalign[4] = {0,1,2,4}; inline int align(int n, int align) { - return (n+(align-1)) & ~(align-1); + return (n + (align - 1)) & ~(align - 1); } void VertexDecoder::SetVertexType(u32 fmt) @@ -40,7 +49,7 @@ void VertexDecoder::SetVertexType(u32 fmt) int biggest = 0; size = 0; - + tc = fmt & 0x3; col = (fmt >> 2) & 0x7; nrm = (fmt >> 5) & 0x3; @@ -51,7 +60,7 @@ void VertexDecoder::SetVertexType(u32 fmt) nweights = ((fmt >> 14) & 0x7)+1; DEBUG_LOG(G3D,"VTYPE: THRU=%i TC=%i COL=%i POS=%i NRM=%i WT=%i NW=%i IDX=%i MC=%i", (int)throughmode, tc,col,pos,nrm,weighttype,nweights,idx,morphcount); - + if (weighttype) { //size = align(size, wtalign[weighttype]); unnecessary diff --git a/GPU/GLES/VertexDecoder.h b/GPU/GLES/VertexDecoder.h index a16725338c..464ebf72a1 100644 --- a/GPU/GLES/VertexDecoder.h +++ b/GPU/GLES/VertexDecoder.h @@ -40,26 +40,27 @@ struct TransformedVertex -// Right now +// Right now // - only contains computed information // - does decoding in nasty branchfilled loops -// Future TODO -// - will compile into lighting fast specialized x86 +// Future TODO +// - will compile into lighting fast specialized x86 and ARM // - will not bother translating components that can be read directly // by OpenGL ES. Will still have to translate 565 colors, and things // like that. DecodedVertex will not be a fixed struct. Will have to // do morphing here. // // We want 100% perf on 1Ghz even in vertex complex games! -class VertexDecoder +class VertexDecoder { public: VertexDecoder() : coloff(0), nrmoff(0), posoff(0) {} ~VertexDecoder() {} - void SetVertexType(u32 fmt); + void SetVertexType(u32 vtype); void DecodeVerts(DecodedVertex *decoded, const void *verts, const void *inds, int prim, int count, int *indexLowerBound, int *indexUpperBound) const; bool hasColor() const { return col != 0; } int VertexSize() const { return size; } + private: u32 fmt; bool throughmode; @@ -81,5 +82,8 @@ private: int idx; int morphcount; int nweights; - }; + +// Debugging utilities +void PrintDecodedVertex(const DecodedVertex &vtx, u32 vtype); + diff --git a/GPU/GLES/VertexShaderGenerator.cpp b/GPU/GLES/VertexShaderGenerator.cpp index e974d9928d..d573942aa4 100644 --- a/GPU/GLES/VertexShaderGenerator.cpp +++ b/GPU/GLES/VertexShaderGenerator.cpp @@ -38,12 +38,24 @@ static char buffer[16384]; #define WRITE(x, ...) p+=sprintf(p, x "\n" __VA_ARGS__) -void ComputeVertexShaderID(VertexShaderID *id) +// prim so we can special case for RECTANGLES :( +void ComputeVertexShaderID(VertexShaderID *id, int prim) { + int doTexture = (gstate.textureMapEnable & 1) && !(gstate.clearmode & 1); + memset(id->d, 0, sizeof(id->d)); id->d[0] = gstate.lmode & 1; id->d[0] |= ((int)gstate.isModeThrough()) << 1; id->d[0] |= ((int)gstate.isFogEnabled()) << 2; + id->d[0] |= doTexture << 3; + + // Bits that we will need: + // lightenable * 4 + // lighttype * 4 + // lightcomp * 4 + // uv gen: + // mapping type + // texshade light choices (ONLY IF uv mapping type is shade) } void WriteLight(char *p, int l) { @@ -61,8 +73,11 @@ char *GenerateVertexShader() int lmode = gstate.lmode & 1; - WRITE("attribute vec4 a_position;"); - WRITE("attribute vec2 a_texcoord;"); + int doTexture = (gstate.textureMapEnable & 1) && !(gstate.clearmode & 1); + + WRITE("attribute vec3 a_position;"); + if (doTexture) + WRITE("attribute vec2 a_texcoord;"); WRITE("attribute vec4 a_color0;"); if (lmode) WRITE("attribute vec4 a_color1;"); @@ -77,18 +92,20 @@ char *GenerateVertexShader() WRITE("varying vec4 v_color0;"); if (lmode) WRITE("varying vec4 v_color1;"); - WRITE("varying vec2 v_texcoord;"); + if (doTexture) + WRITE("varying vec2 v_texcoord;"); if (gstate.isFogEnabled()) WRITE("varying float v_depth;"); WRITE("void main() {"); WRITE(" v_color0 = a_color0;"); if (lmode) WRITE(" v_color1 = a_color1;"); - WRITE(" v_texcoord = a_texcoord;"); + if (doTexture) + WRITE(" v_texcoord = a_texcoord;"); if (gstate.isModeThrough()) { - WRITE(" gl_Position = u_proj_through * a_position;"); + WRITE(" gl_Position = u_proj_through * vec4(a_position, 1.0);"); } else { - WRITE(" gl_Position = u_proj * a_position;"); + WRITE(" gl_Position = u_proj * vec4(a_position, 1.0);"); } if (gstate.isFogEnabled()) { WRITE(" v_depth = gl_Position.z;"); diff --git a/GPU/GLES/VertexShaderGenerator.h b/GPU/GLES/VertexShaderGenerator.h index 10a1fd1e58..4ce2bdb87b 100644 --- a/GPU/GLES/VertexShaderGenerator.h +++ b/GPU/GLES/VertexShaderGenerator.h @@ -46,7 +46,7 @@ struct VertexShaderID } }; -void ComputeVertexShaderID(VertexShaderID *id); +void ComputeVertexShaderID(VertexShaderID *id, int prim); // The return value is only valid until the function is called again. char *GenerateVertexShader(); diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 39adabc391..f11eb33bff 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -79,8 +79,8 @@ struct GPUgstate u32 cmdmem[256]; struct { - int nop; - u32 vaddr, + u32 nop, + vaddr, iaddr, pad00, prim, @@ -226,11 +226,9 @@ struct GPUgstate transferstart, transfersrcpos, transferdstpos, - transfersize - ; + transfersize; u32 pad05[0x63-0x40]; - }; }; diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index 9c56f14567..7dc6b109ee 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -40,7 +40,28 @@ void WindowsHost::SetWindowTitle(const char *message) // Really need a better way to deal with versions. std::string title = "PPSSPP v0.4 - "; title += message; - SetWindowText(mainWindow_, title.c_str()); + + int size = MultiByteToWideChar(CP_UTF8, 0, message, title.size(), NULL, 0); + if (size > 0) + { + wchar_t *utf16_title = new wchar_t[size + 1]; + if (utf16_title) + size = MultiByteToWideChar(CP_UTF8, 0, message, title.size(), utf16_title, size); + else + size = 0; + + if (size > 0) + { + utf16_title[size] = 0; + // Don't use SetWindowTextW because it will internally use DefWindowProcA. + DefWindowProcW(mainWindow_, WM_SETTEXT, 0, (LPARAM) utf16_title); + delete[] utf16_title; + } + } + + // Something went wrong, fall back to using the local codepage. + if (size <= 0) + SetWindowTextA(mainWindow_, title.c_str()); } void WindowsHost::InitSound(PMixer *mixer) diff --git a/Windows/WndMainWindow.cpp b/Windows/WndMainWindow.cpp index 51cd5df02a..a80e17345c 100644 --- a/Windows/WndMainWindow.cpp +++ b/Windows/WndMainWindow.cpp @@ -35,6 +35,9 @@ #include "XPTheme.h" #endif +BOOL g_bFullScreen = FALSE; +RECT rc = {0}; + namespace MainWindow { HWND hwndMain; @@ -81,7 +84,7 @@ namespace MainWindow wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_PPSSPP); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); - wcex.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH); + wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wcex.lpszMenuName = (LPCSTR)IDR_MENU1; wcex.lpszClassName = szWindowClass; wcex.hIconSm = (HICON)LoadImage(hInstance, (LPCTSTR)IDI_PPSSPP, IMAGE_ICON, 16,16,LR_SHARED); @@ -465,8 +468,12 @@ namespace MainWindow g_Config.bIgnoreBadMemAccess = !g_Config.bIgnoreBadMemAccess; UpdateMenus(); break; - //case ID_OPTIONS_FULLSCREEN: - // break; + case ID_OPTIONS_FULLSCREEN: + if(g_bFullScreen) + _ViewNormal(hWnd); + else + _ViewFullScreen(hWnd); + break; case ID_OPTIONS_DISPLAYRAWFRAMEBUFFER: g_Config.bDisplayFramebuffer = !g_Config.bDisplayFramebuffer; @@ -580,7 +587,7 @@ namespace MainWindow case WM_USER+1: disasmWindow[0] = new CDisasm(MainWindow::GetHInstance(), MainWindow::GetHWND(), currentDebugMIPS); DialogManager::AddDlg(disasmWindow[0]); - disasmWindow[0]->Show(TRUE); + disasmWindow[0]->Show(g_Config.bShowDebuggerOnLoad); memoryWindow[0] = new CMemoryDlg(MainWindow::GetHInstance(), MainWindow::GetHWND(), currentDebugMIPS); DialogManager::AddDlg(memoryWindow[0]); if (disasmWindow[0]) @@ -670,6 +677,53 @@ namespace MainWindow { InvalidateRect(hwndDisplay,0,0); } + void _ViewNormal(HWND hWnd) + { + // put caption and border styles back + DWORD dwOldStyle = ::GetWindowLong(hWnd, GWL_STYLE); + DWORD dwNewStyle = dwOldStyle | WS_CAPTION | WS_THICKFRAME; + ::SetWindowLong(hWnd, GWL_STYLE, dwNewStyle); + + // put back the menu bar + ::SetMenu(hWnd, menu); + + // resize to normal view + // NOTE: use SWP_FRAMECHANGED to force redraw non-client + const int x = rc.left; + const int y = rc.top; + const int cx = rc.right - rc.left; + const int cy = rc.bottom - rc.top; + ::SetWindowPos(hWnd, HWND_NOTOPMOST, x, y, cx, cy, SWP_FRAMECHANGED); + + // reset full screen indicator + g_bFullScreen = FALSE; + } + +void _ViewFullScreen(HWND hWnd) +{ + // keep in mind normal window rectangle + ::GetWindowRect(hWnd, &rc); + + // remove caption and border styles + DWORD dwOldStyle = ::GetWindowLong(hWnd, GWL_STYLE); + DWORD dwNewStyle = dwOldStyle & ~(WS_CAPTION | WS_THICKFRAME); + ::SetWindowLong(hWnd, GWL_STYLE, dwNewStyle); + + // remove the menu bar + ::SetMenu(hWnd, NULL); + + // resize to full screen view + // NOTE: use SWP_FRAMECHANGED to force redraw non-client + const int x = 0; + const int y = 0; + const int cx = ::GetSystemMetrics(SM_CXSCREEN); + const int cy = ::GetSystemMetrics(SM_CYSCREEN); + ::SetWindowPos(hWnd, HWND_TOPMOST, x, y, cx, cy, SWP_FRAMECHANGED); + + // set full screen indicator + g_bFullScreen = TRUE; +} + void SetPlaying(const char *text) { diff --git a/Windows/WndMainWindow.h b/Windows/WndMainWindow.h index bc20c80132..0e01330bc4 100644 --- a/Windows/WndMainWindow.h +++ b/Windows/WndMainWindow.h @@ -14,4 +14,6 @@ namespace MainWindow HINSTANCE GetHInstance(); HWND GetDisplayHWND(); void SetPlaying(const char*text); + void _ViewFullScreen(HWND hWnd); + void _ViewNormal(HWND hWnd); } diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 2af9a1b0d2..d3c0c6b5d7 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -55,7 +55,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,243,141,50,14 ICON IDI_PPSSPP,IDC_STATIC,10,9,20,20 LTEXT "PPSSPP",IDC_STATIC,40,8,127,9 - LTEXT "Copyright (c) by Henrik Rydgård 2012",IDC_STATIC,40,33,253,8 + LTEXT "Copyright (c) by Henrik Rydg�rd 2012",IDC_STATIC,40,33,253,8 LTEXT "All trademarks are property of their respective owners.\nThe emulator is for educational and development purposes only and it may not be used to play games you do not legally own.",IDC_STATIC,40,102,253,24 LTEXT "PSP emulator and debugger",IDC_STATIC,40,19,253,8 LTEXT "CISO decompression code by BOOSTER",IDC_STATIC,48,73,240,8 @@ -211,7 +211,7 @@ BEGIN END POPUP "&Options" BEGIN - MENUITEM "&Toggle Full Screen\tAlt+Enter", ID_OPTIONS_FULLSCREEN, GRAYED + MENUITEM "&Toggle Full Screen\tF12", ID_OPTIONS_FULLSCREEN MENUITEM "&Display raw framebuffer", ID_OPTIONS_DISPLAYRAWFRAMEBUFFER MENUITEM "&Buffered rendering", ID_OPTIONS_BUFFEREDRENDERING MENUITEM "&Show debug statistics", ID_OPTIONS_SHOWDEBUGSTATISTICS @@ -317,7 +317,7 @@ BEGIN VK_F5, ID_FILE_REFRESHGAMELIST, VIRTKEY, NOINVERT VK_F2, ID_FILE_SAVESTATE, VIRTKEY, NOINVERT "W", ID_FILE_UNLOAD, VIRTKEY, CONTROL, NOINVERT - VK_RETURN, ID_OPTIONS_FULLSCREEN, VIRTKEY, ALT, NOINVERT + VK_F12, ID_OPTIONS_FULLSCREEN, VIRTKEY, NOINVERT END @@ -344,11 +344,11 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", "PPSSPP PSP emulator" - VALUE "CompanyName", "Henrik Rydgård Inc." + VALUE "CompanyName", "Henrik Rydg�rd Inc." VALUE "FileDescription", "PPSSPP" VALUE "FileVersion", "1, 0, 0, 0" VALUE "InternalName", "s" - VALUE "LegalCopyright", "Copyright (C) 2006-2012 by Henrik Rydgård" + VALUE "LegalCopyright", "Copyright (C) 2006-2012 by Henrik Rydg�rd" VALUE "LegalTrademarks", "All product names are trademarks of their respective owners." VALUE "OriginalFilename", "PPSSPP.exe" VALUE "ProductName", "PPSSPP" diff --git a/android/ab.sh b/android/ab.sh old mode 100644 new mode 100755 diff --git a/android/jni/EmuScreen.cpp b/android/jni/EmuScreen.cpp index 23a1dd541a..b21ab0b36c 100644 --- a/android/jni/EmuScreen.cpp +++ b/android/jni/EmuScreen.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "gfx_es2/glsl_program.h" +#include "gfx_es2/gl_state.h" #include "gfx_es2/fbo.h" #include "input/input_state.h" @@ -153,14 +154,7 @@ void EmuScreen::render() // Reapply the graphics state of the PSP ReapplyGfxState(); - // First attempt at an Android-friendly execution loop. - // We simply run the CPU for 1/60th of a second each frame. If a swap doesn't happen, not sure what the best thing to do is :P - // Also if we happen to get half a frame or something, things will be screwed up so this doesn't actually really work. - // - // I think we need to allocate FBOs per framebuffer and just blit the displayed one here at the end of the frame. - // Also - we should add another option to the core that lets us run it until a vblank event happens or the N cycles have passed - // - then the synchronization would at least not be able to drift off. - + // We just run the CPU until we get to vblank. This will quickly sync up pretty nicely. // The actual number of cycles doesn't matter so much here as we will break due to CORE_NEXTFRAME, most of the time hopefully... int blockTicks = usToCycles(1000000 / 2); @@ -186,8 +180,8 @@ void EmuScreen::render() ui_draw2d.Begin(DBMODE_NORMAL); // Make this configurable. -// if (coreParam.useTouchControls) - DrawGamepad(ui_draw2d); + if (g_Config.bShowTouchControls) + DrawGamepad(ui_draw2d); DrawWatermark(); diff --git a/android/jni/MenuScreens.cpp b/android/jni/MenuScreens.cpp index f98f6986af..2bacdd2310 100644 --- a/android/jni/MenuScreens.cpp +++ b/android/jni/MenuScreens.cpp @@ -240,19 +240,22 @@ void SettingsScreen::render() { int x = 30; int y = 50; UICheckBox(GEN_ID, x, y += 50, "Enable Sound Emulation", ALIGN_TOPLEFT, &g_Config.bEnableSound); - UICheckBox(GEN_ID, x, y += 50, "Show Analog Stick", ALIGN_TOPLEFT, &g_Config.bShowAnalogStick); UICheckBox(GEN_ID, x, y += 50, "Buffered Rendering (may fix flicker)", ALIGN_TOPLEFT, &g_Config.bBufferedRendering); + bool useFastInt = g_Config.iCpuCore == CPU_FASTINTERPRETER; UICheckBox(GEN_ID, x, y += 50, "Slightly faster interpreter (may crash)", ALIGN_TOPLEFT, &useFastInt); - ui_draw2d.DrawText(UBUNTU48, "much faster JIT coming later", x += 50, 0xcFFFFFFF, ALIGN_LEFT); + // ui_draw2d.DrawText(UBUNTU48, "much faster JIT coming later", x, y+=50, 0xcFFFFFFF, ALIGN_LEFT); + UICheckBox(GEN_ID, x, y += 50, "On-screen Touch Controls", ALIGN_TOPLEFT, &g_Config.bShowTouchControls); + if (g_Config.bShowTouchControls) + UICheckBox(GEN_ID, x + 50, y += 50, "Show Analog Stick", ALIGN_TOPLEFT, &g_Config.bShowAnalogStick); g_Config.iCpuCore = useFastInt ? CPU_FASTINTERPRETER : CPU_INTERPRETER; // UICheckBox(GEN_ID, x, y += 50, "Draw raw framebuffer (for some homebrew)", ALIGN_TOPLEFT, &g_Config.bDisplayFramebuffer); if (UIButton(GEN_ID, Pos(dp_xres - 10, dp_yres-10), LARGE_BUTTON_WIDTH, "Back", ALIGN_RIGHT | ALIGN_BOTTOM)) { screenManager()->switchScreen(new MenuScreen()); } - + UIEnd(); glsl_bind(UIShader_Get()); diff --git a/android/jni/NativeApp.cpp b/android/jni/NativeApp.cpp index b3ce01036f..c4052bf84f 100644 --- a/android/jni/NativeApp.cpp +++ b/android/jni/NativeApp.cpp @@ -27,6 +27,7 @@ #include "base/NativeApp.h" #include "file/vfs.h" #include "file/zip_read.h" +#include "gfx_es2/gl_state.h" #include "gfx/gl_lost_manager.h" #include "gfx/texture.h" #include "input/input_state.h" @@ -168,6 +169,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_directory, co LogManager *logman = LogManager::GetInstance(); ILOG("Logman: %p", logman); + bool gfxLog = false; // Parse command line LogTypes::LOG_LEVELS logLevel = LogTypes::LINFO; for (int i = 1; i < argc; i++) { @@ -177,12 +179,20 @@ void NativeInit(int argc, const char *argv[], const char *savegame_directory, co // Enable debug logging logLevel = LogTypes::LDEBUG; break; + case 'g': + gfxLog = true; + break; } } else { - boot_filename = argv[i]; - if (!File::Exists(boot_filename)) - { - fprintf(stdout, "File not found: %s\n", boot_filename.c_str()); + if (boot_filename.empty()) { + boot_filename = argv[i]; + if (!File::Exists(boot_filename)) + { + fprintf(stderr, "File not found: %s\n", boot_filename.c_str()); + exit(1); + } + } else { + fprintf(stderr, "Can only boot one file"); exit(1); } } @@ -204,13 +214,14 @@ void NativeInit(int argc, const char *argv[], const char *savegame_directory, co { LogTypes::LOG_TYPE type = (LogTypes::LOG_TYPE)i; logman->SetEnable(type, true); - logman->SetLogLevel(type, logLevel); + logman->SetLogLevel(type, gfxLog && i == LogTypes::G3D ? LogTypes::LDEBUG : logLevel); #ifdef ANDROID logman->AddListener(type, logger); #endif } // Special hack for G3D as it's very spammy. Need to make a flag for this. - logman->SetLogLevel(LogTypes::G3D, LogTypes::LERROR); + if (!gfxLog) + logman->SetLogLevel(LogTypes::G3D, LogTypes::LERROR); INFO_LOG(BOOT, "Logger inited."); } @@ -257,6 +268,7 @@ void NativeInitGraphics() void NativeRender() { + glstate.Restore(); glViewport(0, 0, pixel_xres, pixel_yres); Matrix4x4 ortho; ortho.setOrtho(0.0f, dp_xres, dp_yres, 0.0f, -1.0f, 1.0f); diff --git a/native b/native index 92bd22ffe5..7ed5811db3 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 92bd22ffe5fd90b1441660b9136fc6dc230399ec +Subproject commit 7ed5811db38f3547f8eec3d3b577dae38405b1e0