From 7f4be8b1b076418ae2d65992610071e0dc0699a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 1 Dec 2012 16:28:00 +0100 Subject: [PATCH 01/18] mac buildfix --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d694d2146e..1f376a937c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,10 +101,10 @@ 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() From 364a78edaf0a1f9a96fb4600d228d58c5dde3279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 1 Dec 2012 23:20:08 +0100 Subject: [PATCH 02/18] Add option to show/hide touch controls --- Core/Config.cpp | 2 ++ Core/Config.h | 1 + android/jni/EmuScreen.cpp | 13 +++---------- android/jni/MenuScreens.cpp | 9 ++++++--- android/jni/NativeApp.cpp | 7 ++++++- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index aa8fb39afa..1f82e9c70a 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -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() @@ -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..a86e7df575 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -44,6 +44,7 @@ public: bool bDisplayFramebuffer; bool bBufferedRendering; + bool bShowTouchControls; bool bShowAnalogStick; bool bShowFPSCounter; bool bShowDebugStats; diff --git a/android/jni/EmuScreen.cpp b/android/jni/EmuScreen.cpp index 23a1dd541a..7fb7bf35bc 100644 --- a/android/jni/EmuScreen.cpp +++ b/android/jni/EmuScreen.cpp @@ -153,14 +153,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 +179,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 9fc656b229..0a4c44f9e5 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..02c77f1cc4 100644 --- a/android/jni/NativeApp.cpp +++ b/android/jni/NativeApp.cpp @@ -168,6 +168,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,6 +178,9 @@ 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]; @@ -210,7 +214,8 @@ void NativeInit(int argc, const char *argv[], const char *savegame_directory, co #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."); } From 67f9f3f73f3c4a03c73b535fac395ab4356b2d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 1 Dec 2012 23:38:18 +0100 Subject: [PATCH 03/18] SDL port: Add DEBUG option to set _DEBUG, add ability to log gfx stuff --- CMakeLists.txt | 5 +++ GPU/GLES/DisplayListInterpreter.cpp | 54 +++++++++++++++-------------- android/jni/NativeApp.cpp | 14 +++++--- 3 files changed, 43 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8de40af433..8666766f28 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) @@ -99,6 +100,10 @@ if (USING_GLES2) add_definitions(-DUSING_GLES2) endif() +if(DEBUG) + add_definitions(-D_DEBUG) +endif() + if(NOT MSVC) # Disable some warnings add_definitions(-Wno-multichar) diff --git a/GPU/GLES/DisplayListInterpreter.cpp b/GPU/GLES/DisplayListInterpreter.cpp index efcad63c1f..4d31aac6d3 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; @@ -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/android/jni/NativeApp.cpp b/android/jni/NativeApp.cpp index 02c77f1cc4..4e7053ed7c 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/gl_state.h" #include "gfx/gl_lost_manager.h" #include "gfx/texture.h" #include "input/input_state.h" @@ -183,10 +184,15 @@ void NativeInit(int argc, const char *argv[], const char *savegame_directory, co 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); } } From ad59c7f46d1301db24d6fcad09f61f9c780d66fd Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 3 Dec 2012 07:44:29 -0800 Subject: [PATCH 04/18] Convert the title to wchars to fix non-ASCII. --- Windows/WindowsHost.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index 9c56f14567..85b317c6c4 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -40,7 +40,27 @@ 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; + SetWindowTextW(mainWindow_, 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) From 346095d5f085984d80b6d9b0589c8afd2931b9cd Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 3 Dec 2012 07:57:28 -0800 Subject: [PATCH 05/18] SetWindowText() was doing ANSI conversion. --- Windows/WindowsHost.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index 85b317c6c4..7dc6b109ee 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -53,7 +53,8 @@ void WindowsHost::SetWindowTitle(const char *message) if (size > 0) { utf16_title[size] = 0; - SetWindowTextW(mainWindow_, utf16_title); + // Don't use SetWindowTextW because it will internally use DefWindowProcA. + DefWindowProcW(mainWindow_, WM_SETTEXT, 0, (LPARAM) utf16_title); delete[] utf16_title; } } From 582b078c2364b69cf0f66d265293c3e8b31455c6 Mon Sep 17 00:00:00 2001 From: jacky400 Date: Wed, 5 Dec 2012 00:04:24 +0800 Subject: [PATCH 06/18] Update Core/Config.cpp --- Core/Config.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index aa8fb39afa..e8cf8f1741 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); @@ -79,7 +79,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); From 0b659e20fd6dd752946056dcfcd0a87372150bd0 Mon Sep 17 00:00:00 2001 From: jacky400 Date: Wed, 5 Dec 2012 00:04:55 +0800 Subject: [PATCH 07/18] Update Core/Config.h --- Core/Config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/Config.h b/Core/Config.h index f7add3be19..0581bb8c79 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -43,7 +43,7 @@ public: bool bIgnoreBadMemAccess; bool bDisplayFramebuffer; bool bBufferedRendering; - + bool bShowDebuggerOnLoad; bool bShowAnalogStick; bool bShowFPSCounter; bool bShowDebugStats; From a072fff4d47baa45b8a14ec50e28e7a987fb76ef Mon Sep 17 00:00:00 2001 From: jacky400 Date: Wed, 5 Dec 2012 00:05:36 +0800 Subject: [PATCH 08/18] Update Windows/WndMainWindow.cpp --- Windows/WndMainWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Windows/WndMainWindow.cpp b/Windows/WndMainWindow.cpp index 51cd5df02a..c0d40527bb 100644 --- a/Windows/WndMainWindow.cpp +++ b/Windows/WndMainWindow.cpp @@ -580,7 +580,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]) From 438099519360c3d90d5df7f6dfc36cba79bec524 Mon Sep 17 00:00:00 2001 From: Kevin Armstrong Date: Sat, 1 Dec 2012 00:03:46 +0000 Subject: [PATCH 09/18] make addmonths work slightly more correctly --- Core/HLE/sceRtc.cpp | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/Core/HLE/sceRtc.cpp b/Core/HLE/sceRtc.cpp index 7d9067a538..36c5b3fc26 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) 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); } From e1a5bf91c30b743bd139a63949103f3e706e1f97 Mon Sep 17 00:00:00 2001 From: Kevin Armstrong Date: Sat, 1 Dec 2012 12:52:42 +0000 Subject: [PATCH 10/18] more rtc changes, getting closer --- Core/HLE/sceRtc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceRtc.cpp b/Core/HLE/sceRtc.cpp index 36c5b3fc26..c63094b2b7 100644 --- a/Core/HLE/sceRtc.cpp +++ b/Core/HLE/sceRtc.cpp @@ -620,7 +620,7 @@ int sceRtcTickAddMonths(u32 destTickPtr, u32 srcTickPtr, int numMonths) { 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; memset(&pt, 0, sizeof(pt)); if (numMonths < 0) From 700921deb30e19b7847bdb16deb6e7eb4a96b1f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 5 Dec 2012 10:45:28 +0700 Subject: [PATCH 11/18] Fix rendering on MacOSX (shader compiler very fussy...). Minor prep for hw transform. --- GPU/GLES/FragmentShaderGenerator.cpp | 12 ++++--- GPU/GLES/ShaderManager.cpp | 28 ++++++++-------- GPU/GLES/ShaderManager.h | 30 +++++++++++++++-- GPU/GLES/TransformPipeline.cpp | 50 ++++++++++++++++------------ GPU/GLES/VertexDecoder.cpp | 15 +++++++-- GPU/GLES/VertexDecoder.h | 16 +++++---- GPU/GLES/VertexShaderGenerator.cpp | 28 ++++++++++++---- GPU/GLES/VertexShaderGenerator.h | 2 +- GPU/GPUState.h | 8 ++--- android/ab.sh | 0 android/jni/EmuScreen.cpp | 1 + android/jni/NativeApp.cpp | 5 +-- native | 2 +- 13 files changed, 128 insertions(+), 69 deletions(-) mode change 100644 => 100755 android/ab.sh diff --git a/GPU/GLES/FragmentShaderGenerator.cpp b/GPU/GLES/FragmentShaderGenerator.cpp index b225c299bf..d240894809 100644 --- a/GPU/GLES/FragmentShaderGenerator.cpp +++ b/GPU/GLES/FragmentShaderGenerator.cpp @@ -21,7 +21,6 @@ #define GLSL_1_3 #endif - #include "FragmentShaderGenerator.h" #include "../ge_constants.h" #include "../GPUState.h" @@ -77,7 +76,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"); @@ -89,7 +90,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"); @@ -98,6 +100,7 @@ char *GenerateFragmentShader() if (gstate.clearmode & 1) { + // Clear mode does not allow any fancy shading. WRITE(p, " v = v_color0;\n"); } else @@ -156,7 +159,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 @@ -169,7 +172,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..93096d67d6 100644 --- a/GPU/GLES/ShaderManager.cpp +++ b/GPU/GLES/ShaderManager.cpp @@ -46,7 +46,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); } } @@ -67,32 +67,30 @@ LinkedShader::LinkedShader(Shader *vs, Shader *fs) glGetProgramInfoLog(program, bufLength, NULL, buf); ERROR_LOG(G3D, "Could not link program:\n %s", buf); 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..9fbe842ca9 100644 --- a/GPU/GLES/ShaderManager.h +++ b/GPU/GLES/ShaderManager.h @@ -53,8 +53,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 +68,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 @@ -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..f6387f5603 100644 --- a/GPU/GLES/VertexShaderGenerator.cpp +++ b/GPU/GLES/VertexShaderGenerator.cpp @@ -38,12 +38,21 @@ 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) { 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; + + // 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 +70,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 +89,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/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 7fb7bf35bc..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" diff --git a/android/jni/NativeApp.cpp b/android/jni/NativeApp.cpp index 4e7053ed7c..c4052bf84f 100644 --- a/android/jni/NativeApp.cpp +++ b/android/jni/NativeApp.cpp @@ -27,7 +27,7 @@ #include "base/NativeApp.h" #include "file/vfs.h" #include "file/zip_read.h" -#include "gfx/gl_state.h" +#include "gfx_es2/gl_state.h" #include "gfx/gl_lost_manager.h" #include "gfx/texture.h" #include "input/input_state.h" @@ -214,7 +214,7 @@ 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 @@ -268,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 From a0d8017c2254d87981aab740702f32d45cfbaa17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 5 Dec 2012 11:13:36 +0700 Subject: [PATCH 12/18] Fix for previous commit --- GPU/GLES/ShaderManager.cpp | 4 ++-- GPU/GLES/ShaderManager.h | 2 +- GPU/GLES/VertexShaderGenerator.cpp | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/GPU/GLES/ShaderManager.cpp b/GPU/GLES/ShaderManager.cpp index 93096d67d6..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 @@ -66,6 +64,8 @@ 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! } return; diff --git a/GPU/GLES/ShaderManager.h b/GPU/GLES/ShaderManager.h index 9fbe842ca9..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 @@ -99,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_; }; diff --git a/GPU/GLES/VertexShaderGenerator.cpp b/GPU/GLES/VertexShaderGenerator.cpp index f6387f5603..d573942aa4 100644 --- a/GPU/GLES/VertexShaderGenerator.cpp +++ b/GPU/GLES/VertexShaderGenerator.cpp @@ -41,10 +41,13 @@ static char buffer[16384]; // 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 From b49e053edd6e14e2d4500644e9d7fb4a29c47e80 Mon Sep 17 00:00:00 2001 From: jacky400 Date: Wed, 5 Dec 2012 14:31:41 +0800 Subject: [PATCH 13/18] Update Windows/WndMainWindow.cpp --- Windows/WndMainWindow.cpp | 60 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/Windows/WndMainWindow.cpp b/Windows/WndMainWindow.cpp index c0d40527bb..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; @@ -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) { From 284597582c3807e025799c1603dfce37ea3e74ad Mon Sep 17 00:00:00 2001 From: jacky400 Date: Wed, 5 Dec 2012 14:32:32 +0800 Subject: [PATCH 14/18] Update Windows/WndMainWindow.h --- Windows/WndMainWindow.h | 2 ++ 1 file changed, 2 insertions(+) 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); } From 7c70a2048a39aaf25b575499039a2842bcd037c7 Mon Sep 17 00:00:00 2001 From: jacky400 Date: Wed, 5 Dec 2012 14:40:13 +0800 Subject: [PATCH 15/18] Update Windows/ppsspp.rc --- Windows/ppsspp.rc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 2af9a1b0d2..4e37789c62 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\tAlt+Enter", 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" From 8ce8400bae85449d9a3274648ab7242d4d961ca8 Mon Sep 17 00:00:00 2001 From: jacky400 Date: Wed, 5 Dec 2012 16:55:02 +0800 Subject: [PATCH 16/18] Update Windows/ppsspp.rc --- Windows/ppsspp.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 4e37789c62..d3c0c6b5d7 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -211,7 +211,7 @@ BEGIN END POPUP "&Options" BEGIN - MENUITEM "&Toggle Full Screen\tAlt+Enter", ID_OPTIONS_FULLSCREEN + 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 From 305a87407b8bc486c96ea4368a41a0a2e1fb6043 Mon Sep 17 00:00:00 2001 From: jacky400 Date: Wed, 5 Dec 2012 19:50:25 +0800 Subject: [PATCH 17/18] Update Core/HLE/sceSas.cpp Implement sceSasGetPauseFlag() in sascore.cpp --- Core/HLE/sceSas.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) 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? From 595ff3b1fb4c76177059388c33edf11b4f867228 Mon Sep 17 00:00:00 2001 From: jacky400 Date: Wed, 5 Dec 2012 20:22:11 +0800 Subject: [PATCH 18/18] Update Core/HLE/sceAudio.cpp Too spam and change it to debug log --- Core/HLE/sceAudio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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;