mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-10-07 10:53:31 +00:00
Merge branch 'master' of github.com:hrydgard/ppsspp
This commit is contained in:
commit
739b747e02
1
.gitignore
vendored
1
.gitignore
vendored
@ -32,3 +32,4 @@ Memstick
|
||||
android/ui_atlas.zim
|
||||
__testoutput.txt
|
||||
__testerror.txt
|
||||
ppge_atlas.zim.png
|
||||
|
@ -245,6 +245,9 @@
|
||||
<ClCompile Include="x64Emitter.cpp" />
|
||||
<ClCompile Include="x86Disasm.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
@ -77,4 +77,7 @@
|
||||
<ClCompile Include="Action.cpp" />
|
||||
<ClCompile Include="ThunkArm.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -129,7 +129,7 @@ void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask)
|
||||
#ifdef __APPLE__
|
||||
thread_policy_set(pthread_mach_thread_np(thread),
|
||||
THREAD_AFFINITY_POLICY, (integer_t *)&mask, 1);
|
||||
#elif defined __linux__ || defined BSD4_4
|
||||
#elif (defined __linux__ || defined BSD4_4) && !defined(ANDROID)
|
||||
cpu_set_t cpu_set;
|
||||
CPU_ZERO(&cpu_set);
|
||||
|
||||
|
@ -54,6 +54,8 @@ set(SRCS
|
||||
FileSystems/DirectoryFileSystem.cpp
|
||||
FileSystems/MetaFileSystem.cpp
|
||||
Util/BlockAllocator.cpp
|
||||
Util/ppge_atlas.cpp
|
||||
Util/PPGeDraw.cpp
|
||||
CPU.cpp
|
||||
CoreTiming.cpp
|
||||
Config.cpp
|
||||
|
@ -236,6 +236,8 @@
|
||||
<ClCompile Include="PSPMixer.cpp" />
|
||||
<ClCompile Include="System.cpp" />
|
||||
<ClCompile Include="Util\BlockAllocator.cpp" />
|
||||
<ClCompile Include="Util\PPGeDraw.cpp" />
|
||||
<ClCompile Include="Util\ppge_atlas.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Config.h" />
|
||||
@ -337,6 +339,8 @@
|
||||
<ClInclude Include="System.h" />
|
||||
<ClInclude Include="Util\BlockAllocator.h" />
|
||||
<ClInclude Include="Util\Pool.h" />
|
||||
<ClInclude Include="Util\PPGeDraw.h" />
|
||||
<ClInclude Include="Util\ppge_atlas.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\android\jni\Android.mk" />
|
||||
|
@ -291,6 +291,12 @@
|
||||
<ClCompile Include="HLE\sceImpose.cpp">
|
||||
<Filter>HLE\Libraries</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Util\PPGeDraw.cpp">
|
||||
<Filter>Util</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Util\ppge_atlas.cpp">
|
||||
<Filter>Util</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ELF\ElfReader.h">
|
||||
@ -530,6 +536,12 @@
|
||||
<ClInclude Include="HLE\sceImpose.h">
|
||||
<Filter>HLE\Libraries</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Util\PPGeDraw.h">
|
||||
<Filter>Util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Util\ppge_atlas.h">
|
||||
<Filter>Util</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CMakeLists.txt" />
|
||||
|
@ -116,12 +116,25 @@ PSPFileInfo MetaFileSystem::GetFileInfo(std::string filename)
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Not sure where this should live. Seems a bit wrong putting it in common
|
||||
bool stringEndsWith (std::string const &fullString, std::string const &ending)
|
||||
{
|
||||
if (fullString.length() >= ending.length()) {
|
||||
return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<PSPFileInfo> MetaFileSystem::GetDirListing(std::string path)
|
||||
{
|
||||
std::string of;
|
||||
if (path.find(':') == std::string::npos)
|
||||
{
|
||||
path = currentDirectory + "/" + path;
|
||||
if (!stringEndsWith(currentDirectory, "/"))
|
||||
{
|
||||
path = currentDirectory + "/" + path;
|
||||
}
|
||||
DEBUG_LOG(HLE,"GetFileInfo: Expanded path to %s", path.c_str());
|
||||
}
|
||||
IFileSystem *system;
|
||||
|
@ -98,8 +98,8 @@ const HLEFunction sceRtc[] =
|
||||
{
|
||||
{0xC41C2853, sceRtcGetTickResolution, "sceRtcGetTickResolution"},
|
||||
{0x3f7ad767, sceRtcGetCurrentTick, "sceRtcGetCurrentTick"},
|
||||
{0x011F03C1, 0, "sceRtcGetAccumulativeTime"},
|
||||
{0x029CA3B3, 0, "sceRtcGetAccumlativeTime"},
|
||||
{0x011F03C1, sceRtcGetCurrentTick, "sceRtcGetAccumulativeTime"},
|
||||
{0x029CA3B3, sceRtcGetCurrentTick, "sceRtcGetAccumlativeTime"},
|
||||
{0x4cfa57b0, 0, "sceRtcGetCurrentClock"},
|
||||
{0xE7C27D1B, sceRtcGetCurrentClockLocalTime, "sceRtcGetCurrentClockLocalTime"},
|
||||
{0x34885E0D, 0, "sceRtcConvertUtcToLocalTime"},
|
||||
|
@ -46,7 +46,6 @@ struct CtrlLatch {
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// STATE BEGIN
|
||||
static bool ctrlInited = false;
|
||||
@ -79,6 +78,12 @@ void UpdateLatch() {
|
||||
oldButtons = ctrl.buttons;
|
||||
}
|
||||
|
||||
|
||||
u32 __CtrlPeekButtons()
|
||||
{
|
||||
return ctrl.buttons;
|
||||
}
|
||||
|
||||
// Functions so that the rest of the emulator can control what the sceCtrl interface should return
|
||||
// to the game:
|
||||
|
||||
|
@ -36,3 +36,6 @@ void __CtrlButtonDown(u32 buttonBit);
|
||||
void __CtrlButtonUp(u32 buttonBit);
|
||||
// -1 to 1, try to keep it in the circle
|
||||
void __CtrlSetAnalog(float x, float y);
|
||||
|
||||
// For use by internal UI like MsgDialog
|
||||
u32 __CtrlPeekButtons();
|
@ -15,18 +15,6 @@
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#if defined(ANDROID) || defined(BLACKBERRY)
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#else
|
||||
#include <GL/glew.h>
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
//#include "base/timeutil.h"
|
||||
@ -46,6 +34,9 @@
|
||||
#include "../../GPU/GLES/Framebuffer.h"
|
||||
#include "../../GPU/GLES/ShaderManager.h"
|
||||
#include "../../GPU/GPUState.h"
|
||||
#include "../../GPU/GPUInterface.h"
|
||||
// Internal drawing library
|
||||
#include "../Util/PPGeDraw.h"
|
||||
|
||||
extern ShaderManager shaderManager;
|
||||
|
||||
@ -138,6 +129,21 @@ void hleEnterVblank(u64 userdata, int cyclesLate)
|
||||
framebufIsLatched = false;
|
||||
}
|
||||
|
||||
// Draw screen overlays before blitting. Saves and restores the Ge context.
|
||||
|
||||
/*
|
||||
if (g_Config.bShowGPUStats)
|
||||
{
|
||||
char stats[512];
|
||||
sprintf(stats, "Draw calls")
|
||||
}*/
|
||||
|
||||
/*
|
||||
PPGeBegin();
|
||||
PPGeDrawImage(I_LOGO, 5, 5, 0, 0xFFFFFFFF);
|
||||
PPGeDrawText("This is PPGeDraw speaking", 10, 100, 0, 0.5f, 0xFFFFFFFF);
|
||||
PPGeEnd();
|
||||
*/
|
||||
// Yeah, this has to be the right moment to end the frame. Should possibly blit the right buffer
|
||||
// depending on what's set in sceDisplaySetFramebuf, in order to support half-framerate games -
|
||||
// an initial hack could be to NOT end the frame if the buffer didn't change? that should work okay.
|
||||
@ -179,9 +185,7 @@ u32 sceDisplaySetMode(u32 unknown, u32 xres, u32 yres)
|
||||
DEBUG_LOG(HLE,"sceDisplaySetMode(%d,%d,%d)",unknown,xres,yres);
|
||||
host->BeginFrame();
|
||||
|
||||
glClearColor(0,0,0,1);
|
||||
// glClearColor(1,0,1,1);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
gpu->InitClear();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -255,6 +259,13 @@ void sceDisplayWaitVblankStartCB()
|
||||
__KernelCheckCallbacks();
|
||||
}
|
||||
|
||||
void sceDisplayWaitVblankStartMultiCB()
|
||||
{
|
||||
DEBUG_LOG(HLE,"sceDisplayWaitVblankStartMultiCB()");
|
||||
__KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, true);
|
||||
__KernelCheckCallbacks();
|
||||
}
|
||||
|
||||
void sceDisplayGetVcount()
|
||||
{
|
||||
// Too spammy
|
||||
@ -293,7 +304,7 @@ const HLEFunction sceDisplay[] =
|
||||
{0x984C27E7,sceDisplayWaitVblankStart, "sceDisplayWaitVblankStart"},
|
||||
{0x8EB9EC49,sceDisplayWaitVblankCB, "sceDisplayWaitVblankCB"},
|
||||
{0x46F186C3,sceDisplayWaitVblankStartCB, "sceDisplayWaitVblankStartCB"},
|
||||
{0x77ed8b3a,0,"sceDisplayWaitVblankStartMultiCB"},
|
||||
{0x77ed8b3a,sceDisplayWaitVblankStartMultiCB,"sceDisplayWaitVblankStartMultiCB"},
|
||||
|
||||
{0xdba6c4c4,&WrapF_V<sceDisplayGetFramePerSec>,"sceDisplayGetFramePerSec"},
|
||||
{0x773dd3a3,sceDisplayGetCurrentHcount,"sceDisplayGetCurrentHcount"},
|
||||
|
@ -154,14 +154,42 @@ void sceGeUnsetCallback(u32 cbID)
|
||||
sceKernelReleaseSubIntrHandler(PSP_GE_INTR, PSP_GE_SUBINTR_SIGNAL);
|
||||
}
|
||||
|
||||
void sceGeSaveContext()
|
||||
// Points to 512 32-bit words, where we can probably layout the context however we want
|
||||
// unless some insane game pokes it and relies on it...
|
||||
u32 sceGeSaveContext(u32 ctxAddr)
|
||||
{
|
||||
ERROR_LOG(HLE,"UNIMPL sceGeSaveContext()");
|
||||
DEBUG_LOG(HLE,"sceGeSaveContext(%08x)", ctxAddr);
|
||||
|
||||
if (sizeof(gstate) > 512 * 4) {
|
||||
ERROR_LOG(HLE, "AARGH! sizeof(gstate) has grown too large!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Let's just dump gstate.
|
||||
if (Memory::IsValidAddress(ctxAddr)) {
|
||||
Memory::WriteStruct(ctxAddr, &gstate);
|
||||
}
|
||||
|
||||
// This action should probably be pushed to the end of the queue of the display thread -
|
||||
// when we have one.
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sceGeRestoreContext()
|
||||
u32 sceGeRestoreContext(u32 ctxAddr)
|
||||
{
|
||||
ERROR_LOG(HLE,"UNIMPL sceGeRestoreContext()");
|
||||
DEBUG_LOG(HLE,"sceGeRestoreContext(%08x)", ctxAddr);
|
||||
|
||||
if (sizeof(gstate) > 512 * 4) {
|
||||
ERROR_LOG(HLE, "AARGH! sizeof(gstate) has grown too large!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Memory::IsValidAddress(ctxAddr)) {
|
||||
Memory::ReadStruct(ctxAddr, &gstate);
|
||||
}
|
||||
ReapplyGfxState();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sceGeGetMtx()
|
||||
@ -195,8 +223,8 @@ const HLEFunction sceGe_user[] =
|
||||
{0xB77905EA,&sceGeEdramSetAddrTranslation,"sceGeEdramSetAddrTranslation"},
|
||||
{0xDC93CFEF,0,"sceGeGetCmd"},
|
||||
{0x57C8945B,&sceGeGetMtx,"sceGeGetMtx"},
|
||||
{0x438A385A,0,"sceGeSaveContext"},
|
||||
{0x0BF608FB,0,"sceGeRestoreContext"},
|
||||
{0x438A385A,&WrapU_U<sceGeSaveContext>,"sceGeSaveContext"},
|
||||
{0x0BF608FB,&WrapU_U<sceGeRestoreContext>,"sceGeRestoreContext"},
|
||||
{0x5FB86AB0,0,"sceGeListDeQueue"},
|
||||
};
|
||||
|
||||
|
@ -38,3 +38,10 @@ void Register_sceGe_user();
|
||||
|
||||
void __GeInit();
|
||||
void __GeShutdown();
|
||||
|
||||
|
||||
// Export functions for use by Util/PPGe
|
||||
u32 sceGeRestoreContext(u32 ctxAddr);
|
||||
u32 sceGeSaveContext(u32 ctxAddr);
|
||||
|
||||
u32 sceGeListEnQueue(u32 listAddress, u32 stallAddress, u32 callbackId, u32 optParamAddr);
|
||||
|
@ -39,7 +39,7 @@ static u32 iButtonValue = 0;
|
||||
|
||||
u32 sceImposeGetBatteryIconStatus(u32 chargingPtr, u32 iconStatusPtr)
|
||||
{
|
||||
DEBUG_LOG(HLE,"%i=sceImposeGetBatteryIconStatus(%08x, %08x)", chargingPtr, iconStatusPtr);
|
||||
DEBUG_LOG(HLE, "sceImposeGetBatteryIconStatus(%08x, %08x)", chargingPtr, iconStatusPtr);
|
||||
if (Memory::IsValidAddress(chargingPtr))
|
||||
Memory::Write_U32(1, chargingPtr);
|
||||
if (Memory::IsValidAddress(iconStatusPtr))
|
||||
@ -49,7 +49,7 @@ u32 sceImposeGetBatteryIconStatus(u32 chargingPtr, u32 iconStatusPtr)
|
||||
|
||||
u32 sceImposeSetLanguageMode(u32 languageVal, u32 buttonVal)
|
||||
{
|
||||
DEBUG_LOG(HLE,"%i=sceImposeSetLanguageMode(%08x, %08x)", languageVal, buttonVal);
|
||||
DEBUG_LOG(HLE, "sceImposeSetLanguageMode(%08x, %08x)", languageVal, buttonVal);
|
||||
iLanguage = languageVal;
|
||||
iButtonValue = buttonVal;
|
||||
return 0;
|
||||
@ -57,7 +57,7 @@ u32 sceImposeSetLanguageMode(u32 languageVal, u32 buttonVal)
|
||||
|
||||
u32 sceImposeGetLanguageMode(u32 languagePtr, u32 btnPtr)
|
||||
{
|
||||
DEBUG_LOG(HLE,"%i=sceImposeGetLanguageMode(%08x, %08x)", languagePtr, btnPtr);
|
||||
DEBUG_LOG(HLE, "sceImposeGetLanguageMode(%08x, %08x)", languagePtr, btnPtr);
|
||||
if (Memory::IsValidAddress(languagePtr))
|
||||
Memory::Write_U32(iLanguage, languagePtr);
|
||||
if (Memory::IsValidAddress(btnPtr))
|
||||
|
@ -49,6 +49,8 @@
|
||||
#include "sceUtility.h"
|
||||
#include "sceUmd.h"
|
||||
|
||||
#include "../Util/PPGeDraw.h"
|
||||
|
||||
extern MetaFileSystem pspFileSystem;
|
||||
|
||||
/*
|
||||
@ -78,6 +80,9 @@ void __KernelInit()
|
||||
__PowerInit();
|
||||
__UtilityInit();
|
||||
__UmdInit();
|
||||
|
||||
// "Internal" PSP libraries
|
||||
__PPGeInit();
|
||||
|
||||
kernelRunning = true;
|
||||
INFO_LOG(HLE, "Kernel initialized.");
|
||||
@ -94,6 +99,8 @@ void __KernelShutdown()
|
||||
INFO_LOG(HLE, "Shutting down kernel - %i kernel objects alive", kernelObjects.GetCount());
|
||||
kernelObjects.Clear();
|
||||
|
||||
__PPGeShutdown();
|
||||
|
||||
__GeShutdown();
|
||||
__AudioShutdown();
|
||||
__IoShutdown();
|
||||
|
@ -1288,8 +1288,8 @@ u32 __KernelCreateCallback(const char *name, u32 entrypoint, u32 commonArg)
|
||||
SceUID id = kernelObjects.Create(cb);
|
||||
|
||||
cb->nc.size = sizeof(NativeCallback);
|
||||
strcpy(cb->nc.name, name);
|
||||
|
||||
strncpy(cb->nc.name, name, 32);
|
||||
|
||||
cb->nc.entrypoint = entrypoint;
|
||||
cb->nc.threadId = __KernelGetCurThread();
|
||||
cb->nc.commonArgument = commonArg;
|
||||
|
@ -31,6 +31,7 @@
|
||||
u8 umdActivated = 1;
|
||||
u32 umdStatus = 0;
|
||||
u32 umdErrorStat = 0;
|
||||
static int driveCBId= -1;
|
||||
|
||||
|
||||
#define PSP_UMD_TYPE_GAME 0x10
|
||||
@ -46,6 +47,7 @@ void __UmdInit() {
|
||||
umdActivated = 1;
|
||||
umdStatus = 0;
|
||||
umdErrorStat = 0;
|
||||
driveCBId = -1;
|
||||
}
|
||||
|
||||
u8 __KernelUmdGetState()
|
||||
@ -120,12 +122,21 @@ u32 sceUmdDeactivate(u32 unknown, const char *name)
|
||||
u32 sceUmdRegisterUMDCallBack(u32 cbId)
|
||||
{
|
||||
DEBUG_LOG(HLE,"0=sceUmdRegisterUMDCallback(id=%i)",PARAM(0));
|
||||
if (driveCBId == -1)
|
||||
{
|
||||
driveCBId = cbId;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(HLE," 0=sceUmdRegisterUMDCallback(id=%i) callback overwrite attempt",PARAM(0));
|
||||
}
|
||||
return __KernelRegisterCallback(THREAD_CALLBACK_UMD, cbId);
|
||||
}
|
||||
|
||||
u32 sceUmdUnRegisterUMDCallBack(u32 cbId)
|
||||
{
|
||||
DEBUG_LOG(HLE,"0=sceUmdUnRegisterUMDCallBack(id=%i)",PARAM(0));
|
||||
driveCBId = -1;
|
||||
return __KernelUnregisterCallback(THREAD_CALLBACK_UMD, cbId);
|
||||
}
|
||||
|
||||
@ -147,25 +158,37 @@ u32 sceUmdGetDriveStat()
|
||||
void sceUmdWaitDriveStat()
|
||||
{
|
||||
u32 stat = PARAM(0);
|
||||
ERROR_LOG(HLE,"UNIMPL 0=sceUmdWaitDriveStat(stat = %08x)", stat);
|
||||
//if ((stat & __KernelUmdGetState()) != stat)
|
||||
// __KernelWaitCurThread(WAITTYPE_UMD, 0, stat, 0, 0); //__KernelWaitCurThread(WAITTYPE_UMD, 0);
|
||||
DEBUG_LOG(HLE,"HACK 0=sceUmdWaitDriveStat(stat = %08x)", stat);
|
||||
if ((stat & __KernelUmdGetState()) != stat)
|
||||
__KernelWaitCurThread(WAITTYPE_UMD, 0, stat, 0, 0); //__KernelWaitCurThread(WAITTYPE_UMD, 0);
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
void sceUmdWaitDriveStatWithTimer()
|
||||
{
|
||||
u32 stat = PARAM(0);
|
||||
ERROR_LOG(HLE,"UNIMPL 0=sceUmdWaitDriveStatWithTimer(stat = %08x)", stat);
|
||||
//__KernelWaitCurThread(WAITTYPE_UMD, 0);
|
||||
u32 timeout = PARAM(1);
|
||||
DEBUG_LOG(HLE,"HACK 0=sceUmdWaitDriveStatWithTimer(stat = %08x)", stat);
|
||||
if ((stat & __KernelUmdGetState()) != stat)
|
||||
__KernelWaitCurThread(WAITTYPE_UMD, 0, stat, 0, 0); //__KernelWaitCurThread(WAITTYPE_UMD, 0);
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
void sceUmdWaitDriveStatCB()
|
||||
{
|
||||
u32 stat = PARAM(0);
|
||||
ERROR_LOG(HLE,"UNIMPL 0=sceUmdWaitDriveStatCB(stat = %08x)", stat);
|
||||
//__KernelWaitCurThread(WAITTYPE_UMD, 0);
|
||||
DEBUG_LOG(HLE,"HACK 0=sceUmdWaitDriveStatCB(stat = %08x)", stat);
|
||||
// Immediately notify
|
||||
RETURN(0);
|
||||
if (driveCBId != -1)
|
||||
{
|
||||
__KernelNotifyCallbackType(THREAD_CALLBACK_UMD, driveCBId, __KernelUmdGetState()&stat);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(HLE, "HACK 0=sceUmdWaitDriveStatCB(stat = %08x) attempting to call unset callback", stat);
|
||||
}
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "sceKernelThread.h"
|
||||
#include "sceUtility.h"
|
||||
|
||||
#include "sceCtrl.h"
|
||||
#include "../Util/PPGeDraw.h"
|
||||
|
||||
enum SceUtilitySavedataType
|
||||
{
|
||||
@ -196,7 +198,7 @@ void sceUtilitySavedataInitStart()
|
||||
{
|
||||
SceUtilitySavedataParam *param = (SceUtilitySavedataParam*)Memory::GetPointer(PARAM(0));
|
||||
|
||||
DEBUG_LOG(HLE,"sceUtilitySavedataInitStart(%08x)", PARAM(0));
|
||||
DEBUG_LOG(HLE,"sceUtilitySavedataInitStart(%08x)", PARAM(0));
|
||||
DEBUG_LOG(HLE,"Mode: %i", param->mode);
|
||||
if (param->mode == 0) //load
|
||||
{
|
||||
@ -212,9 +214,11 @@ void sceUtilitySavedataInitStart()
|
||||
|
||||
__UtilityInitStart();
|
||||
|
||||
|
||||
// Returning 0 here breaks Bust a Move Deluxe! But should be the right thing to do...
|
||||
// At least Cohort Chess expects this to return 0 or it locks up..
|
||||
// The fix is probably to fully implement sceUtility so that it actually works.
|
||||
// RETURN(0);
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
void sceUtilitySavedataShutdownStart()
|
||||
@ -288,17 +292,22 @@ struct pspMessageDialog
|
||||
u32 buttonPressed; // 0=?, 1=Yes, 2=No, 3=Back
|
||||
};
|
||||
|
||||
u32 messageDialogAddr;
|
||||
|
||||
void sceUtilityMsgDialogInitStart()
|
||||
{
|
||||
DEBUG_LOG(HLE,"FAKE sceUtilityMsgDialogInitStart(%i)", PARAM(0));
|
||||
pspMessageDialog *dlg = (pspMessageDialog *)Memory::GetPointer(PARAM(0));
|
||||
if (dlg->type == 0) // number
|
||||
u32 structAddr = PARAM(0);
|
||||
DEBUG_LOG(HLE,"FAKE sceUtilityMsgDialogInitStart(%i)", structAddr);
|
||||
messageDialogAddr = structAddr;
|
||||
pspMessageDialog messageDialog;
|
||||
Memory::ReadStruct(messageDialogAddr, &messageDialog);
|
||||
if (messageDialog.type == 0) // number
|
||||
{
|
||||
INFO_LOG(HLE, "MsgDialog: %08x", dlg->errorNum);
|
||||
INFO_LOG(HLE, "MsgDialog: %08x", messageDialog.errorNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG(HLE, "MsgDialog: %s", dlg->string);
|
||||
INFO_LOG(HLE, "MsgDialog: %s", messageDialog.string);
|
||||
}
|
||||
__UtilityInitStart();
|
||||
}
|
||||
@ -312,8 +321,78 @@ void sceUtilityMsgDialogShutdownStart()
|
||||
|
||||
void sceUtilityMsgDialogUpdate()
|
||||
{
|
||||
DEBUG_LOG(HLE,"FAKE sceUtilityMsgDialogUpdate(%i)", PARAM(0));
|
||||
__UtilityUpdate();
|
||||
DEBUG_LOG(HLE,"sceUtilityMsgDialogUpdate(%i)", PARAM(0));
|
||||
|
||||
switch (utilityDialogState) {
|
||||
case SCE_UTILITY_STATUS_FINISHED:
|
||||
utilityDialogState = SCE_UTILITY_STATUS_SHUTDOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (utilityDialogState != SCE_UTILITY_STATUS_RUNNING)
|
||||
{
|
||||
RETURN(0);
|
||||
return;
|
||||
}
|
||||
|
||||
pspMessageDialog messageDialog;
|
||||
Memory::ReadStruct(messageDialogAddr, &messageDialog);
|
||||
const char *text;
|
||||
if (messageDialog.type == 0) {
|
||||
char temp[256];
|
||||
sprintf(temp, "Error code: %08x", messageDialog.errorNum);
|
||||
text = temp;
|
||||
} else {
|
||||
text = messageDialog.string;
|
||||
}
|
||||
|
||||
PPGeBegin();
|
||||
|
||||
PPGeDraw4Patch(I_BUTTON, 0, 0, 480, 272, 0xcFFFFFFF);
|
||||
PPGeDrawText(text, 50, 50, PPGE_ALIGN_LEFT, 0.5f, 0xFFFFFFFF);
|
||||
|
||||
static u32 lastButtons = 0;
|
||||
u32 buttons = __CtrlPeekButtons();
|
||||
|
||||
if (messageDialog.options & 0x10) //yesnobutton
|
||||
{
|
||||
PPGeDrawImage(I_CROSS, 80, 220, 0, 0xFFFFFFFF);
|
||||
PPGeDrawText("Yes", 140, 220, PPGE_ALIGN_HCENTER, 1.0f, 0xFFFFFFFF);
|
||||
PPGeDrawImage(I_CIRCLE, 200, 220, 0, 0xFFFFFFFF);
|
||||
PPGeDrawText("No", 260, 220, PPGE_ALIGN_HCENTER, 1.0f, 0xFFFFFFFF);
|
||||
PPGeDrawImage(I_TRIANGLE, 320, 220, 0, 0xcFFFFFFF);
|
||||
PPGeDrawText("Back", 380, 220, PPGE_ALIGN_HCENTER, 1.0f, 0xcFFFFFFF);
|
||||
if (!lastButtons) {
|
||||
if (buttons & CTRL_TRIANGLE) {
|
||||
messageDialog.buttonPressed = 3; // back
|
||||
utilityDialogState = SCE_UTILITY_STATUS_FINISHED;
|
||||
} else if (buttons & CTRL_CROSS) {
|
||||
messageDialog.buttonPressed = 1;
|
||||
utilityDialogState = SCE_UTILITY_STATUS_FINISHED;
|
||||
} else if (buttons & CTRL_CIRCLE) {
|
||||
messageDialog.buttonPressed = 2;
|
||||
utilityDialogState = SCE_UTILITY_STATUS_FINISHED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PPGeDrawImage(I_CROSS, 150, 220, 0, 0xFFFFFFFF);
|
||||
PPGeDrawText("OK", 480/2, 220, PPGE_ALIGN_HCENTER, 1.0f, 0xFFFFFFFF);
|
||||
if (!lastButtons) {
|
||||
if (buttons & (CTRL_CROSS | CTRL_CIRCLE)) { // accept both
|
||||
messageDialog.buttonPressed = 1;
|
||||
utilityDialogState = SCE_UTILITY_STATUS_FINISHED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lastButtons = buttons;
|
||||
|
||||
Memory::WriteStruct(messageDialogAddr, &messageDialog);
|
||||
|
||||
PPGeEnd();
|
||||
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
@ -323,6 +402,9 @@ void sceUtilityMsgDialogGetStatus()
|
||||
RETURN(__UtilityGetStatus());
|
||||
}
|
||||
|
||||
|
||||
// On screen keyboard
|
||||
|
||||
void sceUtilityOskInitStart()
|
||||
{
|
||||
DEBUG_LOG(HLE,"FAKE sceUtilityOskInitStart(%i)", PARAM(0));
|
||||
|
331
Core/Util/PPGeDraw.cpp
Normal file
331
Core/Util/PPGeDraw.cpp
Normal file
@ -0,0 +1,331 @@
|
||||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "PPGeDraw.h"
|
||||
#include "../GPU/ge_constants.h"
|
||||
#include "../GPU/GPUState.h"
|
||||
#include "../GPU/GPUInterface.h"
|
||||
#include "../HLE/sceKernel.h"
|
||||
#include "../HLE/sceKernelMemory.h"
|
||||
#include "../HLE/sceGe.h"
|
||||
#include "../MemMap.h"
|
||||
#include "image/zim_load.h"
|
||||
#include "gfx/texture_atlas.h"
|
||||
#include "../System.h"
|
||||
|
||||
static u32 atlasPtr;
|
||||
|
||||
struct PPGeVertex {
|
||||
u16 u, v;
|
||||
u32 color;
|
||||
s16 x, y; u16 z;
|
||||
};
|
||||
|
||||
u32 savedContextPtr;
|
||||
u32 savedContextSize = 512 * 4;
|
||||
|
||||
// Display list writer
|
||||
u32 dlPtr;
|
||||
u32 dlWritePtr;
|
||||
u32 dlSize = 0x10000; // should be enough for a frame of gui...
|
||||
|
||||
u32 dataPtr;
|
||||
u32 dataWritePtr;
|
||||
u32 dataSize = 0x10000; // should be enough for a frame of gui...
|
||||
|
||||
// Vertex collector
|
||||
u32 vertexStart;
|
||||
u32 vertexCount;
|
||||
|
||||
//only 0xFFFFFF of data is used
|
||||
static void WriteCmd(u8 cmd, u32 data) {
|
||||
Memory::Write_U32((cmd << 24) | (data & 0xFFFFFF), dlWritePtr);
|
||||
dlWritePtr += 4;
|
||||
}
|
||||
|
||||
static void WriteCmdAddrWithBase(u8 cmd, u32 addr) {
|
||||
WriteCmd(GE_CMD_BASE, (addr >> 8) & 0xFF0000);
|
||||
WriteCmd(cmd, addr & 0xFFFFFF);
|
||||
}
|
||||
|
||||
/*
|
||||
static void WriteCmdFloat(u8 cmd, float f) {
|
||||
union {
|
||||
float fl;
|
||||
u32 u;
|
||||
} conv;
|
||||
conv.fl = f;
|
||||
WriteCmd(cmd, conv.u >> 8);
|
||||
}*/
|
||||
|
||||
static void BeginVertexData() {
|
||||
vertexCount = 0;
|
||||
vertexStart = dataWritePtr;
|
||||
}
|
||||
|
||||
static void Vertex(float x, float y, float u, float v, u32 color = 0xFFFFFFFF)
|
||||
{
|
||||
PPGeVertex vtx;
|
||||
vtx.x = x - 0.5f; vtx.y = y - 0.5f; vtx.z = 0;
|
||||
vtx.u = u * 256 - 0.5f; vtx.v = v * 256 - 0.5f;
|
||||
vtx.color = color;
|
||||
Memory::WriteStruct(dataWritePtr, &vtx);
|
||||
vertexCount++;
|
||||
dataWritePtr += sizeof(vtx);
|
||||
}
|
||||
|
||||
static void EndVertexDataAndDraw(int prim) {
|
||||
WriteCmdAddrWithBase(GE_CMD_VADDR, vertexStart);
|
||||
WriteCmd(GE_CMD_PRIM, (prim << 16) | vertexCount);
|
||||
}
|
||||
|
||||
void __PPGeInit()
|
||||
{
|
||||
if (PSP_CoreParameter().gpuCore == GPU_NULL) {
|
||||
// Let's just not bother.
|
||||
dlPtr = 0;
|
||||
NOTICE_LOG(HLE, "Not initializing PPGe - GPU is NullGpu");
|
||||
return;
|
||||
}
|
||||
u8 *imageData;
|
||||
int width;
|
||||
int height;
|
||||
int flags;
|
||||
if (!LoadZIM("ppge_atlas.zim", &width, &height, &flags, &imageData)) {
|
||||
ERROR_LOG(HLE, "PPGe init failed - no atlas texture. PPGe stuff will not be drawn.");
|
||||
return;
|
||||
}
|
||||
|
||||
u32 atlasSize = height * width * 2; // it's a 4444 texture
|
||||
dlPtr = kernelMemory.Alloc(dlSize, false, "PPGe Display List");
|
||||
dataPtr = kernelMemory.Alloc(dataSize, false, "PPGe Vertex Data");
|
||||
atlasPtr = kernelMemory.Alloc(atlasSize, false, "PPGe Atlas Texture");
|
||||
savedContextPtr = kernelMemory.Alloc(savedContextSize, false, "PPGe Saved Context");
|
||||
|
||||
u16 *imagePtr = (u16 *)imageData;
|
||||
// component order change
|
||||
for (int i = 0; i < width * height; i++) {
|
||||
u16 c = imagePtr[i];
|
||||
int a = c & 0xF;
|
||||
int r = (c >> 4) & 0xF;
|
||||
int g = (c >> 8) & 0xF;
|
||||
int b = (c >> 12) & 0xF;
|
||||
c = (a << 12) | (r << 8) | (g << 4) | b;
|
||||
imagePtr[i] = c;
|
||||
}
|
||||
|
||||
Memory::Memcpy(atlasPtr, imageData, atlasSize);
|
||||
free(imageData);
|
||||
|
||||
NOTICE_LOG(HLE, "PPGe drawing library initialized. DL: %08x Data: %08x Atlas: %08x (%i) Ctx: %08x",
|
||||
dlPtr, dataPtr, atlasPtr, atlasSize, savedContextPtr);
|
||||
}
|
||||
|
||||
void __PPGeShutdown()
|
||||
{
|
||||
kernelMemory.Free(atlasPtr);
|
||||
kernelMemory.Free(dataPtr);
|
||||
kernelMemory.Free(dlPtr);
|
||||
kernelMemory.Free(savedContextPtr);
|
||||
atlasPtr = 0;
|
||||
dataPtr = 0;
|
||||
dlPtr = 0;
|
||||
savedContextPtr = 0;
|
||||
}
|
||||
|
||||
void PPGeBegin()
|
||||
{
|
||||
if (!dlPtr)
|
||||
return;
|
||||
|
||||
// Reset write pointers to start of command and data buffers.
|
||||
dlWritePtr = dlPtr;
|
||||
dataWritePtr = dataPtr;
|
||||
|
||||
// Set up the correct states for UI drawing
|
||||
WriteCmd(GE_CMD_ALPHABLENDENABLE, 1);
|
||||
WriteCmd(GE_CMD_BLENDMODE, 2 | (3 << 4));
|
||||
WriteCmd(GE_CMD_ALPHATESTENABLE, 0);
|
||||
WriteCmd(GE_CMD_COLORTESTENABLE, 0);
|
||||
WriteCmd(GE_CMD_ZTESTENABLE, 0);
|
||||
WriteCmd(GE_CMD_FOGENABLE, 0);
|
||||
WriteCmd(GE_CMD_STENCILTESTENABLE, 0);
|
||||
WriteCmd(GE_CMD_CULLFACEENABLE, 0);
|
||||
WriteCmd(GE_CMD_CLEARMODE, 0); // Normal mode
|
||||
|
||||
WriteCmd(GE_CMD_TEXTUREMAPENABLE, 1);
|
||||
WriteCmd(GE_CMD_TEXSIZE0, 8 | (8 << 8)); // 1 << (7+1) = 256
|
||||
WriteCmd(GE_CMD_TEXMAPMODE, 0 | (1 << 8));
|
||||
WriteCmd(GE_CMD_TEXMODE, 0);
|
||||
WriteCmd(GE_CMD_TEXFORMAT, 2); // 4444
|
||||
WriteCmd(GE_CMD_TEXFILTER, (1 << 8) | 1); // mag = LINEAR min = LINEAR
|
||||
WriteCmd(GE_CMD_TEXWRAP, (1 << 8) | 1); // clamp texture wrapping
|
||||
WriteCmd(GE_CMD_TEXFUNC, (0 << 16) | (1 << 8) | 0); // RGBA texture reads, modulate, no color doubling
|
||||
WriteCmd(GE_CMD_TEXADDR0, atlasPtr & 0xFFFFF0);
|
||||
WriteCmd(GE_CMD_TEXBUFWIDTH0, 256 | ((atlasPtr & 0xFF000000) >> 8));
|
||||
WriteCmd(GE_CMD_TEXFLUSH, 0);
|
||||
|
||||
WriteCmd(GE_CMD_SCISSOR1, (0 << 10) | 0);
|
||||
WriteCmd(GE_CMD_SCISSOR2, (1023 << 10) | 1023);
|
||||
WriteCmd(GE_CMD_MINZ, 0);
|
||||
WriteCmd(GE_CMD_MAXZ, 0xFFFF);
|
||||
|
||||
// Through mode, so we don't have to bother with matrices
|
||||
WriteCmd(GE_CMD_VERTEXTYPE, GE_VTYPE_TC_16BIT | GE_VTYPE_COL_8888 | GE_VTYPE_POS_16BIT | GE_VTYPE_THROUGH);
|
||||
}
|
||||
|
||||
void PPGeEnd()
|
||||
{
|
||||
if (!dlPtr)
|
||||
return;
|
||||
|
||||
WriteCmd(GE_CMD_FINISH, 0);
|
||||
WriteCmd(GE_CMD_END, 0);
|
||||
|
||||
if (dataWritePtr > dataPtr) {
|
||||
sceGeSaveContext(savedContextPtr);
|
||||
gpu->EnableInterrupts(false);
|
||||
|
||||
// We actually drew something
|
||||
u32 list = sceGeListEnQueue(dlPtr, dlWritePtr, 0, 0);
|
||||
DEBUG_LOG(HLE, "PPGe enqueued display list %i", list);
|
||||
// TODO: Might need to call some internal trickery function when this is actually synchronous.
|
||||
// sceGeListSync(u32 displayListID, 1); //0 : wait for completion 1:check and return
|
||||
gpu->EnableInterrupts(true);
|
||||
sceGeRestoreContext(savedContextPtr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void PPGeMeasureText(const char *text, float scale, float *w, float *h) {
|
||||
const AtlasFont &atlasfont = *ppge_atlas.fonts[0];
|
||||
unsigned char cval;
|
||||
float wacc = 0;
|
||||
int lines = 1;
|
||||
while ((cval = *text++) != '\0') {
|
||||
if (cval < 32) continue;
|
||||
if (cval > 127) continue;
|
||||
if (cval == '\n') {
|
||||
wacc = 0;
|
||||
lines++;
|
||||
}
|
||||
AtlasChar c = atlasfont.chars[cval - 32];
|
||||
wacc += c.wx * scale;
|
||||
}
|
||||
if (w) *w = wacc;
|
||||
if (h) *h = atlasfont.height * scale * lines;
|
||||
}
|
||||
|
||||
static void PPGeDoAlign(int flags, float *x, float *y, float *w, float *h) {
|
||||
if (flags & PPGE_ALIGN_HCENTER) *x -= *w / 2;
|
||||
if (flags & PPGE_ALIGN_RIGHT) *x -= *w;
|
||||
if (flags & PPGE_ALIGN_VCENTER) *y -= *h / 2;
|
||||
if (flags & PPGE_ALIGN_BOTTOM) *y -= *h;
|
||||
}
|
||||
|
||||
// Draws some text using the one font we have.
|
||||
// Mostly stolen from DrawBuffer.
|
||||
void PPGeDrawText(const char *text, float x, float y, int align, float scale, u32 color)
|
||||
{
|
||||
if (!dlPtr)
|
||||
return;
|
||||
const AtlasFont &atlasfont = *ppge_atlas.fonts[0];
|
||||
unsigned char cval;
|
||||
float w, h;
|
||||
PPGeMeasureText(text, scale, &w, &h);
|
||||
if (align) {
|
||||
PPGeDoAlign(align, &x, &y, &w, &h);
|
||||
}
|
||||
BeginVertexData();
|
||||
y += atlasfont.ascend*scale;
|
||||
float sx = x;
|
||||
while ((cval = *text++) != '\0') {
|
||||
if (cval == '\n') {
|
||||
y += atlasfont.height * scale;
|
||||
x = sx;
|
||||
continue;
|
||||
}
|
||||
if (cval < 32) continue;
|
||||
if (cval > 127) continue;
|
||||
AtlasChar c = atlasfont.chars[cval - 32];
|
||||
float cx1 = x + c.ox * scale;
|
||||
float cy1 = y + c.oy * scale;
|
||||
float cx2 = x + (c.ox + c.pw) * scale;
|
||||
float cy2 = y + (c.oy + c.ph) * scale;
|
||||
Vertex(cx1, cy1, c.sx, c.sy, color);
|
||||
Vertex(cx2, cy2, c.ex, c.ey, color);
|
||||
x += c.wx * scale;
|
||||
}
|
||||
EndVertexDataAndDraw(GE_PRIM_RECTANGLES);
|
||||
}
|
||||
|
||||
// Draws a "4-patch" for button-like things that can be resized
|
||||
void PPGeDraw4Patch(int atlasImage, float x, float y, float w, float h, u32 color)
|
||||
{
|
||||
if (!dlPtr)
|
||||
return;
|
||||
const AtlasImage &img = ppge_images[atlasImage];
|
||||
float borderx = img.w / 2;
|
||||
float bordery = img.h / 2;
|
||||
float u1 = img.u1, uhalf = (img.u1 + img.u2) / 2, u2 = img.u2;
|
||||
float v1 = img.v1, vhalf = (img.v1 + img.v2) / 2, v2 = img.v2;
|
||||
float xmid1 = x + borderx;
|
||||
float xmid2 = x + w - borderx;
|
||||
float ymid1 = y + bordery;
|
||||
float ymid2 = y + h - bordery;
|
||||
float x2 = x + w;
|
||||
float y2 = y + h;
|
||||
BeginVertexData();
|
||||
// Top row
|
||||
Vertex(x, y, u1, v1, color);
|
||||
Vertex(xmid1, ymid1, uhalf, vhalf, color);
|
||||
Vertex(xmid1, y, uhalf, v1, color);
|
||||
Vertex(xmid2, ymid1, uhalf, vhalf, color);
|
||||
Vertex(xmid2, y, uhalf, v1, color);
|
||||
Vertex(x2, ymid1, u2, vhalf, color);
|
||||
// Middle row
|
||||
Vertex(x, ymid1, u1, vhalf, color);
|
||||
Vertex(xmid1, ymid2, uhalf, vhalf, color);
|
||||
Vertex(xmid1, ymid1, uhalf, vhalf, color);
|
||||
Vertex(xmid2, ymid2, uhalf, vhalf, color);
|
||||
Vertex(xmid2, ymid1, uhalf, vhalf, color);
|
||||
Vertex(x2, ymid2, u2, v2, color);
|
||||
// Bottom row
|
||||
Vertex(x, ymid2, u1, vhalf, color);
|
||||
Vertex(xmid1, y2, uhalf, v2, color);
|
||||
Vertex(xmid1, ymid2, uhalf, vhalf, color);
|
||||
Vertex(xmid2, y2, uhalf, v2, color);
|
||||
Vertex(xmid2, ymid2, uhalf, vhalf, color);
|
||||
Vertex(x2, y2, u2, v2, color);
|
||||
EndVertexDataAndDraw(GE_PRIM_RECTANGLES);
|
||||
}
|
||||
|
||||
// Just blits an image to the screen, multiplied with the color.
|
||||
void PPGeDrawImage(int atlasImage, float x, float y, int align, u32 color)
|
||||
{
|
||||
if (!dlPtr)
|
||||
return;
|
||||
|
||||
const AtlasImage &img = ppge_atlas.images[atlasImage];
|
||||
float w = img.w;
|
||||
float h = img.h;
|
||||
BeginVertexData();
|
||||
Vertex(x, y, img.u1, img.v1, color);
|
||||
Vertex(x + w, y + h, img.u2, img.v2, color);
|
||||
EndVertexDataAndDraw(GE_PRIM_RECTANGLES);
|
||||
}
|
||||
|
65
Core/Util/PPGeDraw.h
Normal file
65
Core/Util/PPGeDraw.h
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../Globals.h"
|
||||
#include "ppge_atlas.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PPGeDraw: Super simple internal drawing API for 2D overlays like sceUtility messageboxes
|
||||
// etc. Goes through the Ge emulation so that it's 100% portable - will work
|
||||
// splendidly on any existing GPU backend, including the future software backend.
|
||||
|
||||
// Uploads the necessary texture atlas and other data to kernel RAM, and reserves
|
||||
// space for the display list. The PSP must be inited.
|
||||
void __PPGeInit();
|
||||
|
||||
// Just frees up the allocated kernel memory.
|
||||
void __PPGeShutdown();
|
||||
|
||||
// Save and restore the Ge context. PPGeEnd() kicks off the generated display list.
|
||||
void PPGeBegin();
|
||||
void PPGeEnd();
|
||||
|
||||
enum {
|
||||
PPGE_ALIGN_LEFT = 0,
|
||||
PPGE_ALIGN_RIGHT = 16,
|
||||
PPGE_ALIGN_TOP = 0,
|
||||
PPGE_ALIGN_BOTTOM = 1,
|
||||
PPGE_ALIGN_HCENTER = 4,
|
||||
PPGE_ALIGN_VCENTER = 8,
|
||||
PPGE_ALIGN_VBASELINE = 32, // text only, possibly not yet working
|
||||
|
||||
PPGE_ALIGN_CENTER = PPGE_ALIGN_HCENTER | PPGE_ALIGN_VCENTER,
|
||||
PPGE_ALIGN_TOPLEFT = PPGE_ALIGN_TOP | PPGE_ALIGN_LEFT,
|
||||
PPGE_ALIGN_TOPRIGHT = PPGE_ALIGN_TOP | PPGE_ALIGN_RIGHT,
|
||||
PPGE_ALIGN_BOTTOMLEFT = PPGE_ALIGN_BOTTOM | PPGE_ALIGN_LEFT,
|
||||
PPGE_ALIGN_BOTTOMRIGHT = PPGE_ALIGN_BOTTOM | PPGE_ALIGN_RIGHT,
|
||||
};
|
||||
|
||||
// These functions must be called between PPGeBegin and PPGeEnd.
|
||||
|
||||
// Draws some text using the one font we have.
|
||||
void PPGeDrawText(const char *text, float x, float y, int align, float scale = 1.0f, u32 color = 0xFFFFFFFF);
|
||||
|
||||
// Draws a "4-patch" for button-like things that can be resized
|
||||
void PPGeDraw4Patch(int atlasImage, float x, float y, float w, float h, u32 color = 0xFFFFFFFF);
|
||||
|
||||
// Just blits an image to the screen, multiplied with the color.
|
||||
void PPGeDrawImage(int atlasImage, float x, float y, int align, u32 color = 0xFFFFFFFF);
|
||||
|
125
Core/Util/ppge_atlas.cpp
Normal file
125
Core/Util/ppge_atlas.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
// C++ generated by atlastool from ppge_atlasscript.txt (hrydgard@gmail.com)
|
||||
|
||||
#include "ppge_atlas.h"
|
||||
|
||||
const AtlasFont font_UBUNTU24 = {
|
||||
-1.375000f, // padding
|
||||
36.687500f, // height
|
||||
26.937500f, // ascend
|
||||
0.750000f, // distslope
|
||||
{
|
||||
{0.972656f, 0.000000f, 0.976563f, 0.003906f, -2.0000f, -2.0000f, 7.0625f, 1, 1}, // 32
|
||||
{0.531250f, 0.675781f, 0.562500f, 0.777344f, -0.3750f, -23.1250f, 6.3750f, 8, 26}, // 33
|
||||
{0.246094f, 0.718750f, 0.292969f, 0.765625f, -0.5000f, -23.0625f, 10.2500f, 12, 12}, // 34
|
||||
{0.000000f, 0.191406f, 0.074219f, 0.292969f, -1.5625f, -23.0625f, 15.3125f, 19, 26}, // 35
|
||||
{0.527344f, 0.464844f, 0.589844f, 0.566406f, -1.1875f, -23.0625f, 13.8125f, 16, 26}, // 36
|
||||
{0.867188f, 0.105469f, 0.957031f, 0.207031f, -0.7500f, -23.3750f, 20.9375f, 23, 26}, // 37
|
||||
{0.000000f, 0.296875f, 0.066406f, 0.398438f, -0.9375f, -23.0625f, 14.1250f, 17, 26}, // 38
|
||||
{0.656250f, 0.140625f, 0.683594f, 0.187500f, -0.5000f, -23.0625f, 5.3125f, 7, 12}, // 39
|
||||
{0.425781f, 0.449219f, 0.472656f, 0.589844f, 0.3750f, -26.9375f, 10.7500f, 12, 36}, // 40
|
||||
{0.703125f, 0.453125f, 0.750000f, 0.593750f, -1.3750f, -26.9375f, 10.7500f, 12, 36}, // 41
|
||||
{0.933594f, 0.691406f, 0.996094f, 0.750000f, -1.2500f, -23.0625f, 12.8750f, 16, 15}, // 42
|
||||
{0.867188f, 0.691406f, 0.929688f, 0.753906f, -0.5000f, -18.3750f, 14.7500f, 16, 16}, // 43
|
||||
{0.593750f, 0.464844f, 0.625000f, 0.511719f, -0.5000f, -4.9375f, 5.7500f, 8, 12}, // 44
|
||||
{0.148438f, 0.191406f, 0.187500f, 0.214844f, -1.4375f, -12.6250f, 7.1250f, 10, 6}, // 45
|
||||
{0.421875f, 0.316406f, 0.453125f, 0.343750f, -0.5000f, -4.9375f, 6.1250f, 8, 7}, // 46
|
||||
{0.363281f, 0.421875f, 0.421875f, 0.535156f, -3.0625f, -23.0625f, 9.1250f, 15, 29}, // 47
|
||||
{0.070313f, 0.304688f, 0.136719f, 0.406250f, -0.7500f, -23.0625f, 15.4375f, 17, 26}, // 48
|
||||
{0.960938f, 0.105469f, 0.996094f, 0.207031f, -1.7500f, -23.0625f, 6.6250f, 9, 26}, // 49
|
||||
{0.781250f, 0.312500f, 0.847656f, 0.414063f, -0.8125f, -23.0625f, 14.3750f, 17, 26}, // 50
|
||||
{0.820313f, 0.527344f, 0.878906f, 0.628906f, -1.1875f, -23.0625f, 12.8750f, 15, 26}, // 51
|
||||
{0.406250f, 0.210938f, 0.476563f, 0.312500f, -1.6250f, -23.0625f, 13.8125f, 18, 26}, // 52
|
||||
{0.351563f, 0.316406f, 0.417969f, 0.417969f, -0.7500f, -23.0625f, 14.8750f, 17, 26}, // 53
|
||||
{0.628906f, 0.316406f, 0.695313f, 0.417969f, -0.7500f, -23.0625f, 14.9375f, 17, 26}, // 54
|
||||
{0.000000f, 0.507813f, 0.062500f, 0.609375f, -1.5000f, -23.0625f, 12.1250f, 16, 26}, // 55
|
||||
{0.859375f, 0.210938f, 0.929688f, 0.312500f, -0.8750f, -23.0625f, 15.5625f, 18, 26}, // 56
|
||||
{0.851563f, 0.316406f, 0.917969f, 0.417969f, -0.8750f, -23.0625f, 15.0000f, 17, 26}, // 57
|
||||
{0.660156f, 0.527344f, 0.691406f, 0.597656f, -0.3125f, -15.4375f, 6.5625f, 8, 18}, // 58
|
||||
{0.277344f, 0.128906f, 0.308594f, 0.218750f, -0.3125f, -15.4375f, 6.5625f, 8, 23}, // 59
|
||||
{0.335938f, 0.644531f, 0.398438f, 0.714844f, -0.5000f, -19.5000f, 14.7500f, 16, 18}, // 60
|
||||
{0.035156f, 0.707031f, 0.097656f, 0.753906f, -0.5000f, -16.3750f, 14.7500f, 16, 12}, // 61
|
||||
{0.660156f, 0.683594f, 0.722656f, 0.753906f, -0.5000f, -19.5000f, 14.7500f, 16, 18}, // 62
|
||||
{0.066406f, 0.515625f, 0.128906f, 0.617188f, -1.7500f, -23.0625f, 12.3750f, 16, 26}, // 63
|
||||
{0.191406f, 0.128906f, 0.273438f, 0.222656f, -0.8750f, -19.5625f, 18.5000f, 21, 24}, // 64
|
||||
{0.277344f, 0.222656f, 0.347656f, 0.324219f, -1.8125f, -23.0625f, 14.1875f, 18, 26}, // 65
|
||||
{0.222656f, 0.328125f, 0.289063f, 0.429688f, -0.5000f, -23.0625f, 15.0625f, 17, 26}, // 66
|
||||
{0.203125f, 0.539063f, 0.261719f, 0.640625f, -0.7500f, -23.0625f, 12.6875f, 15, 26}, // 67
|
||||
{0.140625f, 0.332031f, 0.207031f, 0.433594f, -0.5000f, -23.0625f, 15.5000f, 17, 26}, // 68
|
||||
{0.347656f, 0.539063f, 0.406250f, 0.640625f, -0.5000f, -23.0625f, 12.8750f, 15, 26}, // 69
|
||||
{0.132813f, 0.554688f, 0.191406f, 0.656250f, -0.5000f, -23.0625f, 11.8750f, 15, 26}, // 70
|
||||
{0.421875f, 0.343750f, 0.488281f, 0.445313f, -0.7500f, -23.0625f, 15.2500f, 17, 26}, // 71
|
||||
{0.699219f, 0.347656f, 0.765625f, 0.449219f, -0.5000f, -23.0625f, 15.8750f, 17, 26}, // 72
|
||||
{0.402344f, 0.695313f, 0.433594f, 0.796875f, -0.4375f, -23.0625f, 6.2500f, 8, 26}, // 73
|
||||
{0.527344f, 0.570313f, 0.585938f, 0.671875f, -1.7500f, -23.0625f, 11.8125f, 15, 26}, // 74
|
||||
{0.921875f, 0.355469f, 0.988281f, 0.457031f, -0.5000f, -23.0625f, 14.5000f, 17, 26}, // 75
|
||||
{0.222656f, 0.226563f, 0.277344f, 0.328125f, -0.5000f, -23.0625f, 11.1875f, 14, 26}, // 76
|
||||
{0.320313f, 0.117188f, 0.402344f, 0.218750f, -0.5000f, -23.0625f, 19.7500f, 21, 26}, // 77
|
||||
{0.492188f, 0.359375f, 0.558594f, 0.460938f, -0.5625f, -23.0625f, 15.8125f, 17, 26}, // 78
|
||||
{0.148438f, 0.226563f, 0.218750f, 0.328125f, -0.7500f, -23.0625f, 16.1250f, 18, 26}, // 79
|
||||
{0.562500f, 0.359375f, 0.628906f, 0.460938f, -0.5000f, -23.0625f, 14.5625f, 17, 26}, // 80
|
||||
{0.507813f, 0.125000f, 0.578125f, 0.234375f, -0.7500f, -23.0625f, 16.3125f, 18, 28}, // 81
|
||||
{0.000000f, 0.402344f, 0.066406f, 0.503906f, -0.5000f, -23.0625f, 15.4375f, 17, 26}, // 82
|
||||
{0.070313f, 0.410156f, 0.136719f, 0.511719f, -1.3125f, -23.0625f, 13.6875f, 17, 26}, // 83
|
||||
{0.753906f, 0.523438f, 0.816406f, 0.625000f, -1.7500f, -23.0625f, 12.3125f, 16, 26}, // 84
|
||||
{0.480469f, 0.238281f, 0.550781f, 0.339844f, -0.6250f, -23.0625f, 16.3125f, 18, 26}, // 85
|
||||
{0.554688f, 0.253906f, 0.625000f, 0.355469f, -1.8125f, -23.0625f, 13.8125f, 18, 26}, // 86
|
||||
{0.867188f, 0.000000f, 0.968750f, 0.101563f, -1.7500f, -23.0625f, 22.2500f, 26, 26}, // 87
|
||||
{0.769531f, 0.417969f, 0.835938f, 0.519531f, -1.5625f, -23.0625f, 13.5625f, 17, 26}, // 88
|
||||
{0.292969f, 0.421875f, 0.359375f, 0.523438f, -1.9375f, -23.0625f, 12.5625f, 17, 26}, // 89
|
||||
{0.281250f, 0.527344f, 0.343750f, 0.628906f, -1.0000f, -23.0625f, 13.0625f, 16, 26}, // 90
|
||||
{0.910156f, 0.460938f, 0.957031f, 0.601563f, 0.3750f, -26.9375f, 10.7500f, 12, 36}, // 91
|
||||
{0.140625f, 0.437500f, 0.199219f, 0.550781f, -2.0000f, -23.0625f, 9.1250f, 15, 29}, // 92
|
||||
{0.476563f, 0.464844f, 0.523438f, 0.605469f, -1.3750f, -26.9375f, 10.7500f, 12, 36}, // 93
|
||||
{0.726563f, 0.714844f, 0.781250f, 0.761719f, -1.1250f, -23.0625f, 11.4375f, 14, 12}, // 94
|
||||
{0.785156f, 0.718750f, 0.847656f, 0.742188f, -2.0000f, 0.0625f, 11.6250f, 16, 6}, // 95
|
||||
{0.566406f, 0.718750f, 0.617188f, 0.753906f, -0.5000f, -24.9375f, 11.9375f, 13, 9}, // 96
|
||||
{0.000000f, 0.613281f, 0.066406f, 0.695313f, -1.0000f, -18.6875f, 14.4375f, 17, 21}, // 97
|
||||
{0.632813f, 0.421875f, 0.699219f, 0.523438f, -0.5000f, -23.6875f, 15.3750f, 17, 26}, // 98
|
||||
{0.292969f, 0.328125f, 0.351563f, 0.410156f, -0.7500f, -18.6875f, 12.3750f, 15, 21}, // 99
|
||||
{0.839844f, 0.421875f, 0.906250f, 0.523438f, -0.7500f, -23.6875f, 15.3750f, 17, 26}, // 100
|
||||
{0.734375f, 0.628906f, 0.800781f, 0.710938f, -0.7500f, -18.6875f, 14.5000f, 17, 21}, // 101
|
||||
{0.136719f, 0.660156f, 0.179688f, 0.761719f, -0.5000f, -23.6875f, 8.1250f, 11, 26}, // 102
|
||||
{0.078125f, 0.191406f, 0.144531f, 0.300781f, -0.7500f, -18.6875f, 15.3750f, 17, 28}, // 103
|
||||
{0.210938f, 0.433594f, 0.277344f, 0.535156f, -0.5000f, -23.6875f, 15.6250f, 17, 26}, // 104
|
||||
{0.437500f, 0.695313f, 0.468750f, 0.796875f, -0.4375f, -23.6875f, 6.1875f, 8, 26}, // 105
|
||||
{0.484375f, 0.609375f, 0.527344f, 0.738281f, -3.3750f, -23.6875f, 6.6250f, 11, 33}, // 106
|
||||
{0.593750f, 0.527344f, 0.656250f, 0.628906f, -0.5000f, -23.6875f, 13.6250f, 16, 26}, // 107
|
||||
{0.000000f, 0.699219f, 0.031250f, 0.800781f, -0.5000f, -23.6875f, 6.0625f, 8, 26}, // 108
|
||||
{0.406250f, 0.125000f, 0.503906f, 0.207031f, -0.5000f, -18.6875f, 23.1875f, 25, 21}, // 109
|
||||
{0.265625f, 0.632813f, 0.332031f, 0.714844f, -0.5000f, -18.6875f, 15.6250f, 17, 21}, // 110
|
||||
{0.660156f, 0.597656f, 0.730469f, 0.679688f, -0.7500f, -18.6875f, 15.5625f, 18, 21}, // 111
|
||||
{0.789063f, 0.199219f, 0.855469f, 0.308594f, -0.5000f, -18.6875f, 15.3750f, 17, 28}, // 112
|
||||
{0.656250f, 0.203125f, 0.722656f, 0.312500f, -0.7500f, -18.6875f, 15.3750f, 17, 28}, // 113
|
||||
{0.351563f, 0.222656f, 0.398438f, 0.304688f, -0.6250f, -18.6875f, 9.6875f, 12, 21}, // 114
|
||||
{0.070313f, 0.621094f, 0.132813f, 0.703125f, -1.1250f, -18.6875f, 13.6250f, 16, 21}, // 115
|
||||
{0.195313f, 0.644531f, 0.242188f, 0.746094f, -0.6250f, -23.0625f, 8.9375f, 12, 26}, // 116
|
||||
{0.589844f, 0.632813f, 0.656250f, 0.714844f, -0.6250f, -18.6875f, 15.5000f, 17, 21}, // 117
|
||||
{0.882813f, 0.605469f, 0.953125f, 0.687500f, -1.7500f, -18.6875f, 14.3125f, 18, 21}, // 118
|
||||
{0.683594f, 0.117188f, 0.785156f, 0.199219f, -1.6875f, -18.6875f, 22.4375f, 26, 21}, // 119
|
||||
{0.410156f, 0.609375f, 0.480469f, 0.691406f, -1.7500f, -18.6875f, 13.8125f, 18, 21}, // 120
|
||||
{0.582031f, 0.140625f, 0.652344f, 0.250000f, -1.7500f, -18.6875f, 14.0000f, 18, 28}, // 121
|
||||
{0.804688f, 0.632813f, 0.863281f, 0.714844f, -1.0000f, -18.6875f, 12.7500f, 15, 21}, // 122
|
||||
{0.726563f, 0.203125f, 0.777344f, 0.343750f, -0.6875f, -26.9375f, 10.9375f, 13, 36}, // 123
|
||||
{0.960938f, 0.460938f, 0.988281f, 0.597656f, 0.6875f, -26.3125f, 7.9375f, 7, 35}, // 124
|
||||
{0.933594f, 0.210938f, 0.984375f, 0.351563f, -1.3750f, -26.9375f, 10.9375f, 13, 36}, // 125
|
||||
{0.296875f, 0.718750f, 0.359375f, 0.750000f, -0.5000f, -14.1875f, 14.7500f, 16, 8}, // 126
|
||||
{0.582031f, 0.000000f, 0.679688f, 0.136719f, -0.5000f, -25.2500f, 23.1250f, 25, 35}, // 127
|
||||
},
|
||||
"UBUNTU24", // name
|
||||
};
|
||||
const AtlasFont *ppge_fonts[1] = {
|
||||
&font_UBUNTU24,
|
||||
};
|
||||
const AtlasImage ppge_images[6] = {
|
||||
{0.458984f, 0.001953f, 0.576172f, 0.119141f, 31, 31, "I_CROSS"},
|
||||
{0.193359f, 0.001953f, 0.314453f, 0.123047f, 32, 32, "I_CIRCLE"},
|
||||
{0.685547f, 0.001953f, 0.794922f, 0.111328f, 29, 29, "I_SQUARE"},
|
||||
{0.322266f, 0.001953f, 0.451172f, 0.111328f, 34, 29, "I_TRIANGLE"},
|
||||
{0.802734f, 0.001953f, 0.861328f, 0.193359f, 16, 50, "I_BUTTON"},
|
||||
{0.001953f, 0.001953f, 0.185547f, 0.185547f, 48, 48, "I_LOGO"},
|
||||
};
|
||||
const Atlas ppge_atlas = {
|
||||
"ppge_atlas.zim",
|
||||
ppge_fonts, 1,
|
||||
ppge_images, 6,
|
||||
};
|
20
Core/Util/ppge_atlas.h
Normal file
20
Core/Util/ppge_atlas.h
Normal file
@ -0,0 +1,20 @@
|
||||
// Header generated by atlastool from ppge_atlasscript.txt (hrydgard@gmail.com)
|
||||
|
||||
#pragma once
|
||||
#include "gfx/texture_atlas.h"
|
||||
|
||||
// FONTS_ppge
|
||||
#define UBUNTU24 0
|
||||
|
||||
|
||||
// IMAGES_ppge
|
||||
#define I_CROSS 0
|
||||
#define I_CIRCLE 1
|
||||
#define I_SQUARE 2
|
||||
#define I_TRIANGLE 3
|
||||
#define I_BUTTON 4
|
||||
#define I_LOGO 5
|
||||
|
||||
|
||||
extern const Atlas ppge_atlas;
|
||||
extern const AtlasImage ppge_images[6];
|
@ -76,6 +76,13 @@ bool finished;
|
||||
|
||||
u8 bezierBuf[16000];
|
||||
|
||||
void GLES_GPU::InitClear()
|
||||
{
|
||||
glClearColor(0,0,0,1);
|
||||
// glClearColor(1,0,1,1);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
bool GLES_GPU::ProcessDLQueue()
|
||||
{
|
||||
std::vector<DisplayList>::iterator iter = dlQueue.begin();
|
||||
@ -106,8 +113,8 @@ u32 GLES_GPU::EnqueueList(u32 listpc, u32 stall)
|
||||
{
|
||||
DisplayList dl;
|
||||
dl.id = dlIdGenerator++;
|
||||
dl.listpc = listpc&0xFFFFFFF;
|
||||
dl.stall = stall&0xFFFFFFF;
|
||||
dl.listpc = listpc & 0xFFFFFFF;
|
||||
dl.stall = stall & 0xFFFFFFF;
|
||||
dlQueue.push_back(dl);
|
||||
if (!ProcessDLQueue())
|
||||
return dl.id;
|
||||
@ -160,7 +167,7 @@ void drawBezier(int ucount, int vcount)
|
||||
}
|
||||
|
||||
LinkedShader *linkedShader = shaderManager.ApplyShader();
|
||||
TransformAndDrawPrim(Memory::GetPointer(gstate.vertexAddr), &indices[0], GE_PRIM_TRIANGLES, 3 * 3 * 6, linkedShader, customUV, GE_VTYPE_IDX_16BIT);
|
||||
TransformAndDrawPrim(Memory::GetPointer(gstate_c.vertexAddr), &indices[0], GE_PRIM_TRIANGLES, 3 * 3 * 6, linkedShader, customUV, GE_VTYPE_IDX_16BIT);
|
||||
}
|
||||
|
||||
|
||||
@ -172,6 +179,7 @@ void EnterClearMode(u32 data)
|
||||
glColorMask(colMask, colMask, colMask, alphaMask);
|
||||
glDepthMask(updateZ); // Update Z or not
|
||||
// Note that depth test must be enabled for depth writes to go through! So we use GL_ALWAYS
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
glDisable(GL_CULL_FACE); // ??
|
||||
@ -189,7 +197,7 @@ void LeaveClearMode()
|
||||
glColorMask(1,1,1,1);
|
||||
glEnDis(GL_DEPTH_TEST, gstate.zTestEnable & 1);
|
||||
glDepthFunc(GL_LEQUAL); // TODO
|
||||
|
||||
glEnDis(GL_BLEND, gstate.alphaBlendEnable & 1);
|
||||
// dirtyshader?
|
||||
}
|
||||
|
||||
@ -255,17 +263,17 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
|
||||
switch (cmd)
|
||||
{
|
||||
case GE_CMD_BASE:
|
||||
DEBUG_LOG(G3D,"DL BASE: %06x", data);
|
||||
DEBUG_LOG(G3D,"DL BASE: %06x", data & 0xFFFFFF);
|
||||
break;
|
||||
|
||||
case GE_CMD_VADDR: /// <<8????
|
||||
gstate.vertexAddr = ((gstate.base & 0x00FF0000) << 8)|data;
|
||||
DEBUG_LOG(G3D,"DL VADDR: %06x", gstate.vertexAddr);
|
||||
gstate_c.vertexAddr = ((gstate.base & 0x00FF0000) << 8)|data;
|
||||
DEBUG_LOG(G3D,"DL VADDR: %06x", gstate_c.vertexAddr);
|
||||
break;
|
||||
|
||||
case GE_CMD_IADDR:
|
||||
gstate.indexAddr = ((gstate.base & 0x00FF0000) << 8)|data;
|
||||
DEBUG_LOG(G3D,"DL IADDR: %06x", gstate.indexAddr);
|
||||
gstate_c.indexAddr = ((gstate.base & 0x00FF0000) << 8)|data;
|
||||
DEBUG_LOG(G3D,"DL IADDR: %06x", gstate_c.indexAddr);
|
||||
break;
|
||||
|
||||
case GE_CMD_PRIM:
|
||||
@ -281,15 +289,15 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
|
||||
"TRIANGLE_FAN=5,",
|
||||
"RECTANGLES=6,",
|
||||
};
|
||||
DEBUG_LOG(G3D, "DL DrawPrim type: %s count: %i vaddr= %08x, iaddr= %08x", type<7 ? types[type] : "INVALID", count, gstate.vertexAddr, gstate.indexAddr);
|
||||
DEBUG_LOG(G3D, "DL DrawPrim type: %s count: %i vaddr= %08x, iaddr= %08x", type<7 ? types[type] : "INVALID", count, gstate_c.vertexAddr, gstate_c.indexAddr);
|
||||
|
||||
LinkedShader *linkedShader = shaderManager.ApplyShader();
|
||||
// TODO: Split this so that we can collect sequences of primitives, can greatly speed things up
|
||||
// on platforms where draw calls are expensive like mobile and D3D
|
||||
void *verts = Memory::GetPointer(gstate.vertexAddr);
|
||||
void *verts = Memory::GetPointer(gstate_c.vertexAddr);
|
||||
void *inds = 0;
|
||||
if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE)
|
||||
inds = Memory::GetPointer(gstate.indexAddr);
|
||||
inds = Memory::GetPointer(gstate_c.indexAddr);
|
||||
TransformAndDrawPrim(verts, inds, type, count, linkedShader);
|
||||
}
|
||||
break;
|
||||
@ -348,7 +356,8 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
|
||||
int behaviour = (data >> 16) & 0xFF;
|
||||
int signal = data & 0xFFFF;
|
||||
|
||||
__TriggerInterruptWithArg(PSP_GE_INTR, PSP_GE_SUBINTR_SIGNAL, signal);
|
||||
if (interruptsEnabled_)
|
||||
__TriggerInterruptWithArg(PSP_GE_INTR, PSP_GE_SUBINTR_SIGNAL, signal);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -388,7 +397,8 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
|
||||
|
||||
case GE_CMD_FINISH:
|
||||
DEBUG_LOG(G3D,"DL CMD FINISH");
|
||||
__TriggerInterruptWithArg(PSP_GE_INTR, PSP_GE_SUBINTR_FINISH, 0);
|
||||
if (interruptsEnabled_)
|
||||
__TriggerInterruptWithArg(PSP_GE_INTR, PSP_GE_SUBINTR_FINISH, 0);
|
||||
break;
|
||||
|
||||
case GE_CMD_END:
|
||||
@ -406,7 +416,8 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
|
||||
}
|
||||
|
||||
// This should generate a Reading Ended interrupt
|
||||
// __TriggerInterrupt(PSP_GE_INTR);
|
||||
// if (interruptsEnabled_)
|
||||
// __TriggerInterrupt(PSP_GE_INTR);
|
||||
|
||||
break;
|
||||
|
||||
@ -465,23 +476,23 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
|
||||
break;
|
||||
|
||||
case GE_CMD_TEXSCALEU:
|
||||
gstate.uScale = getFloat24(data);
|
||||
DEBUG_LOG(G3D, "DL Texture U Scale: %f", gstate.uScale);
|
||||
gstate_c.uScale = getFloat24(data);
|
||||
DEBUG_LOG(G3D, "DL Texture U Scale: %f", gstate_c.uScale);
|
||||
break;
|
||||
|
||||
case GE_CMD_TEXSCALEV:
|
||||
gstate.vScale = getFloat24(data);
|
||||
DEBUG_LOG(G3D, "DL Texture V Scale: %f", gstate.vScale);
|
||||
gstate_c.vScale = getFloat24(data);
|
||||
DEBUG_LOG(G3D, "DL Texture V Scale: %f", gstate_c.vScale);
|
||||
break;
|
||||
|
||||
case GE_CMD_TEXOFFSETU:
|
||||
gstate.uOff = getFloat24(data);
|
||||
DEBUG_LOG(G3D, "DL Texture U Offset: %f", gstate.uOff);
|
||||
gstate_c.uOff = getFloat24(data);
|
||||
DEBUG_LOG(G3D, "DL Texture U Offset: %f", gstate_c.uOff);
|
||||
break;
|
||||
|
||||
case GE_CMD_TEXOFFSETV:
|
||||
gstate.vOff = getFloat24(data);
|
||||
DEBUG_LOG(G3D, "DL Texture V Offset: %f", gstate.vOff);
|
||||
gstate_c.vOff = getFloat24(data);
|
||||
DEBUG_LOG(G3D, "DL Texture V Offset: %f", gstate_c.vOff);
|
||||
break;
|
||||
|
||||
case GE_CMD_SCISSOR1:
|
||||
@ -525,7 +536,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
|
||||
break;
|
||||
|
||||
case GE_CMD_TEXADDR0:
|
||||
gstate.textureChanged = true;
|
||||
gstate_c.textureChanged = true;
|
||||
case GE_CMD_TEXADDR1:
|
||||
case GE_CMD_TEXADDR2:
|
||||
case GE_CMD_TEXADDR3:
|
||||
@ -537,7 +548,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
|
||||
break;
|
||||
|
||||
case GE_CMD_TEXBUFWIDTH0:
|
||||
gstate.textureChanged = true;
|
||||
gstate_c.textureChanged = true;
|
||||
case GE_CMD_TEXBUFWIDTH1:
|
||||
case GE_CMD_TEXBUFWIDTH2:
|
||||
case GE_CMD_TEXBUFWIDTH3:
|
||||
@ -557,16 +568,12 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
|
||||
break;
|
||||
|
||||
case GE_CMD_LOADCLUT:
|
||||
// This could be used to "dirty" textures with clut.
|
||||
{
|
||||
u32 clutAttr = ((gstate.clutaddrupper & 0xFF0000)<<8) | (gstate.clutaddr & 0xFFFFFF);
|
||||
if (clutAttr)
|
||||
u32 clutAddr = ((gstate.clutaddrupper & 0xFF0000)<<8) | (gstate.clutaddr & 0xFFFFFF);
|
||||
if (clutAddr)
|
||||
{
|
||||
u16 *clut = (u16*)Memory::GetPointer(clutAttr);
|
||||
if (clut) {
|
||||
int numColors = 16 * (data&0x3F);
|
||||
memcpy(&gstate.paletteMem[0], clut, numColors * 2);
|
||||
}
|
||||
DEBUG_LOG(G3D,"DL Clut load: %i palettes", data);
|
||||
DEBUG_LOG(G3D,"DL Clut load: %08x", clutAddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -629,9 +636,9 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
|
||||
}
|
||||
|
||||
case GE_CMD_TEXSIZE0:
|
||||
gstate.textureChanged=true;
|
||||
gstate.curTextureWidth = 1 << (gstate.texsize[0] & 0xf);
|
||||
gstate.curTextureHeight = 1 << ((gstate.texsize[0]>>8) & 0xf);
|
||||
gstate_c.textureChanged=true;
|
||||
gstate_c.curTextureWidth = 1 << (gstate.texsize[0] & 0xf);
|
||||
gstate_c.curTextureHeight = 1 << ((gstate.texsize[0]>>8) & 0xf);
|
||||
//fall thru - ignoring the mipmap sizes for now
|
||||
case GE_CMD_TEXSIZE1:
|
||||
case GE_CMD_TEXSIZE2:
|
||||
@ -706,7 +713,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
|
||||
int c = n % 3;
|
||||
float val = getFloat24(data);
|
||||
DEBUG_LOG(G3D,"DL Light %i %c pos: %f", l, c+'X', val);
|
||||
gstate.lightpos[l][c] = val;
|
||||
gstate_c.lightpos[l][c] = val;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -720,7 +727,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
|
||||
int c = n % 3;
|
||||
float val = getFloat24(data);
|
||||
DEBUG_LOG(G3D,"DL Light %i %c dir: %f", l, c+'X', val);
|
||||
gstate.lightdir[l][c] = val;
|
||||
gstate_c.lightdir[l][c] = val;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -734,7 +741,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
|
||||
int c = n % 3;
|
||||
float val = getFloat24(data);
|
||||
DEBUG_LOG(G3D,"DL Light %i %c att: %f", l, c+'X', val);
|
||||
gstate.lightatt[l][c] = val;
|
||||
gstate_c.lightatt[l][c] = val;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -749,9 +756,9 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
|
||||
|
||||
int l = (cmd - GE_CMD_LAC0) / 3;
|
||||
int t = (cmd - GE_CMD_LAC0) % 3;
|
||||
gstate.lightColor[t][l].r = r;
|
||||
gstate.lightColor[t][l].g = g;
|
||||
gstate.lightColor[t][l].b = b;
|
||||
gstate_c.lightColor[t][l].r = r;
|
||||
gstate_c.lightColor[t][l].g = g;
|
||||
gstate_c.lightColor[t][l].b = b;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -780,9 +787,9 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
|
||||
break;
|
||||
|
||||
case GE_CMD_PATCHDIVISION:
|
||||
gstate.patch_div_s = data & 0xFF;
|
||||
gstate.patch_div_t = (data >> 8) & 0xFF;
|
||||
DEBUG_LOG(G3D, "DL Patch subdivision: %i x %i", gstate.patch_div_s, gstate.patch_div_t);
|
||||
gstate_c.patch_div_s = data & 0xFF;
|
||||
gstate_c.patch_div_t = (data >> 8) & 0xFF;
|
||||
DEBUG_LOG(G3D, "DL Patch subdivision: %i x %i", gstate_c.patch_div_s, gstate_c.patch_div_t);
|
||||
break;
|
||||
|
||||
case GE_CMD_MATERIALUPDATE:
|
||||
@ -907,7 +914,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff)
|
||||
int index = cmd - GE_CMD_MORPHWEIGHT0;
|
||||
float weight = getFloat24(data);
|
||||
DEBUG_LOG(G3D,"DL MorphWeight %i = %f", index, weight);
|
||||
gstate.morphWeights[index] = weight;
|
||||
gstate_c.morphWeights[index] = weight;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -24,11 +24,17 @@ class ShaderManager;
|
||||
class GLES_GPU : public GPUInterface
|
||||
{
|
||||
public:
|
||||
GLES_GPU() : interruptsEnabled_(true) {}
|
||||
virtual void InitClear();
|
||||
virtual u32 EnqueueList(u32 listpc, u32 stall);
|
||||
virtual void UpdateStall(int listid, u32 newstall);
|
||||
virtual void ExecuteOp(u32 op, u32 diff);
|
||||
virtual bool InterpretList();
|
||||
virtual void DrawSync(int mode);
|
||||
virtual void EnableInterrupts(bool enable) {
|
||||
interruptsEnabled_ = enable;
|
||||
}
|
||||
private:
|
||||
bool ProcessDLQueue();
|
||||
bool interruptsEnabled_;
|
||||
};
|
||||
|
@ -108,7 +108,8 @@ void DisplayDrawer_Init()
|
||||
glUniformMatrix4fv(draw2dprogram->u_viewproj, 1, GL_FALSE, ortho.getReadPtr());
|
||||
glsl_unbind();
|
||||
|
||||
// And an initial clear.
|
||||
// And an initial clear. We don't clear per frame as the games are supposed to handle that
|
||||
// by themselves.
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
|
@ -37,6 +37,9 @@
|
||||
#include "TransformPipeline.h"
|
||||
|
||||
Shader::Shader(const char *code, uint32_t shaderType) {
|
||||
#ifdef _DEBUG
|
||||
source_ = code;
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
// OutputDebugString(code);
|
||||
#endif
|
||||
|
@ -72,8 +72,9 @@ enum
|
||||
struct Shader
|
||||
{
|
||||
Shader(const char *code, uint32_t shaderType);
|
||||
// const char *source;
|
||||
uint32_t shader;
|
||||
private:
|
||||
std::string source_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -238,7 +238,7 @@ void *readIndexedTex(u32 level, u32 texaddr, u32 bytesPerIndex)
|
||||
u32 n = tmpTexBuf32[j];
|
||||
u32 k;
|
||||
for (k = 0; k < 4; k++) {
|
||||
u8 index = (n >> (k * 4)) & 0xff;
|
||||
u8 index = (n >> (k * 8)) & 0xff;
|
||||
tmpTexBuf16[i + k] = clut[GetClutIndex(index)];
|
||||
}
|
||||
}
|
||||
@ -579,8 +579,8 @@ void PSPSetTexture()
|
||||
u32 w = 1 << (gstate.texsize[0] & 0xf);
|
||||
u32 h = 1 << ((gstate.texsize[0]>>8) & 0xf);
|
||||
|
||||
gstate.curTextureHeight=h;
|
||||
gstate.curTextureWidth=w;
|
||||
gstate_c.curTextureWidth=w;
|
||||
gstate_c.curTextureHeight=h;
|
||||
GLenum dstFmt = 0;
|
||||
u32 texByteAlign = 1;
|
||||
|
||||
|
@ -145,9 +145,9 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[
|
||||
Vec3 toLight;
|
||||
|
||||
if (type == GE_LIGHTTYPE_DIRECTIONAL)
|
||||
toLight = Vec3(gstate.lightpos[l]); // lightdir is for spotlights
|
||||
toLight = Vec3(gstate_c.lightpos[l]); // lightdir is for spotlights
|
||||
else
|
||||
toLight = Vec3(gstate.lightpos[l]) - pos;
|
||||
toLight = Vec3(gstate_c.lightpos[l]) - pos;
|
||||
|
||||
bool doSpecular = (comp != GE_LIGHTCOMP_ONLYDIFFUSE);
|
||||
bool poweredDiffuse = comp == GE_LIGHTCOMP_BOTHWITHPOWDIFFUSE;
|
||||
@ -156,7 +156,7 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[
|
||||
if (type != GE_LIGHTTYPE_DIRECTIONAL)
|
||||
{
|
||||
float distance = toLight.Normalize();
|
||||
lightScale = 1.0f / (gstate.lightatt[l][0] + gstate.lightatt[l][1]*distance + gstate.lightatt[l][2]*distance*distance);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -168,7 +168,7 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[
|
||||
if (poweredDiffuse)
|
||||
dot = powf(dot, specCoef_);
|
||||
|
||||
Color4 diff = (gstate.lightColor[1][l] * *diffuse) * (dot * lightScale);
|
||||
Color4 diff = (gstate_c.lightColor[1][l] * *diffuse) * (dot * lightScale);
|
||||
|
||||
// Real PSP specular
|
||||
Vec3 toViewer(0,0,1);
|
||||
@ -184,13 +184,13 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[
|
||||
dot = halfVec * norm;
|
||||
if (dot >= 0)
|
||||
{
|
||||
lightSum1 += (gstate.lightColor[2][l] * *specular * (powf(dot, specCoef_)*lightScale));
|
||||
lightSum1 += (gstate_c.lightColor[2][l] * *specular * (powf(dot, specCoef_)*lightScale));
|
||||
}
|
||||
}
|
||||
dots[l] = dot;
|
||||
if (gstate.lightEnable[l] & 1)
|
||||
{
|
||||
lightSum0 += gstate.lightColor[0][l] * *ambient + diff;
|
||||
lightSum0 += gstate_c.lightColor[0][l] * *ambient + diff;
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,9 +216,9 @@ void TransformAndDrawPrim(void *verts, void *inds, int prim, int vertexCount, Li
|
||||
bool useTexCoord = false;
|
||||
|
||||
// Check if anything needs updating
|
||||
if (gstate.textureChanged)
|
||||
if (gstate_c.textureChanged)
|
||||
{
|
||||
if (gstate.textureMapEnable && !(gstate.clearmode & 1))
|
||||
if ((gstate.textureMapEnable & 1) && !(gstate.clearmode & 1))
|
||||
{
|
||||
PSPSetTexture();
|
||||
useTexCoord = true;
|
||||
@ -356,16 +356,16 @@ void TransformAndDrawPrim(void *verts, void *inds, int prim, int vertexCount, Li
|
||||
}
|
||||
|
||||
if (customUV) {
|
||||
uv[0] = customUV[index * 2 + 0]*gstate.uScale + gstate.uOff;
|
||||
uv[1] = customUV[index * 2 + 1]*gstate.vScale + gstate.vOff;
|
||||
uv[0] = customUV[index * 2 + 0]*gstate_c.uScale + gstate_c.uOff;
|
||||
uv[1] = customUV[index * 2 + 1]*gstate_c.vScale + gstate_c.vOff;
|
||||
} else {
|
||||
// Perform texture coordinate generation after the transform and lighting - one style of UV depends on lights.
|
||||
switch (gstate.texmapmode & 0x3)
|
||||
{
|
||||
case 0: // UV mapping
|
||||
// Texture scale/offset is only performed in this mode.
|
||||
uv[0] = decoded[index].uv[0]*gstate.uScale + gstate.uOff;
|
||||
uv[1] = decoded[index].uv[1]*gstate.vScale + gstate.vOff;
|
||||
uv[0] = decoded[index].uv[0]*gstate_c.uScale + gstate_c.uOff;
|
||||
uv[1] = decoded[index].uv[1]*gstate_c.vScale + gstate_c.vOff;
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
|
@ -121,8 +121,9 @@ void VertexDecoder::SetVertexType(u32 fmt)
|
||||
|
||||
void VertexDecoder::DecodeVerts(DecodedVertex *decoded, const void *verts, const void *inds, int prim, int count, int *indexLowerBound, int *indexUpperBound) const
|
||||
{
|
||||
// TODO: Remove
|
||||
if (morphcount == 1)
|
||||
gstate.morphWeights[0] = 1.0f;
|
||||
gstate_c.morphWeights[0] = 1.0f;
|
||||
|
||||
char *ptr = (char *)verts;
|
||||
|
||||
@ -211,8 +212,8 @@ void VertexDecoder::DecodeVerts(DecodedVertex *decoded, const void *verts, const
|
||||
const u16 *uvdata = (const u16*)(ptr + tcoff);
|
||||
if (throughmode)
|
||||
{
|
||||
uv[0] = (float)uvdata[0] / (float)(gstate.curTextureWidth);
|
||||
uv[1] = (float)uvdata[1] / (float)(gstate.curTextureHeight);
|
||||
uv[0] = (float)uvdata[0] / (float)(gstate_c.curTextureWidth);
|
||||
uv[1] = (float)uvdata[1] / (float)(gstate_c.curTextureHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -273,7 +274,10 @@ void VertexDecoder::DecodeVerts(DecodedVertex *decoded, const void *verts, const
|
||||
break;
|
||||
|
||||
default:
|
||||
c[0]=255; c[1]=255; c[2]=255; c[3]=255;
|
||||
c[0] = 255;
|
||||
c[1] = 255;
|
||||
c[2] = 255;
|
||||
c[3] = 255;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -281,7 +285,7 @@ void VertexDecoder::DecodeVerts(DecodedVertex *decoded, const void *verts, const
|
||||
memset(normal, 0, sizeof(float)*3);
|
||||
for (int n = 0; n < morphcount; n++)
|
||||
{
|
||||
float multiplier = gstate.morphWeights[n];
|
||||
float multiplier = gstate_c.morphWeights[n];
|
||||
if (gstate.reversenormals & 0xFFFFFF) {
|
||||
multiplier = -multiplier;
|
||||
}
|
||||
@ -358,7 +362,7 @@ void VertexDecoder::DecodeVerts(DecodedVertex *decoded, const void *verts, const
|
||||
{
|
||||
const float *fv = (const float*)(ptr + onesize_*n + posoff);
|
||||
for (int j = 0; j < 3; j++)
|
||||
v[j] += fv[j] * gstate.morphWeights[n];
|
||||
v[j] += fv[j] * gstate_c.morphWeights[n];
|
||||
}
|
||||
break;
|
||||
|
||||
@ -368,7 +372,7 @@ void VertexDecoder::DecodeVerts(DecodedVertex *decoded, const void *verts, const
|
||||
if (throughmode) multiplier = 1.0f;
|
||||
const short *sv = (const short*)(ptr + onesize_*n + posoff);
|
||||
for (int j = 0; j < 3; j++)
|
||||
v[j] += (sv[j] * multiplier) * gstate.morphWeights[n];
|
||||
v[j] += (sv[j] * multiplier) * gstate_c.morphWeights[n];
|
||||
}
|
||||
break;
|
||||
|
||||
@ -376,7 +380,7 @@ void VertexDecoder::DecodeVerts(DecodedVertex *decoded, const void *verts, const
|
||||
{
|
||||
const s8 *sv = (const s8*)(ptr + onesize_*n + posoff);
|
||||
for (int j = 0; j < 3; j++)
|
||||
v[j] += (sv[j] / 127.f) * gstate.morphWeights[n];
|
||||
v[j] += (sv[j] / 127.f) * gstate_c.morphWeights[n];
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -22,9 +22,13 @@
|
||||
class GPUInterface
|
||||
{
|
||||
public:
|
||||
virtual void InitClear() = 0;
|
||||
virtual u32 EnqueueList(u32 listpc, u32 stall) = 0;
|
||||
virtual void UpdateStall(int listid, u32 newstall) = 0;
|
||||
virtual void ExecuteOp(u32 op, u32 diff) = 0;
|
||||
virtual bool InterpretList() = 0;
|
||||
virtual void DrawSync(int mode) = 0;
|
||||
|
||||
// Internal hack to avoid interrupts from "PPGe" drawing (utility UI, etc)
|
||||
virtual void EnableInterrupts(bool enable) = 0;
|
||||
};
|
||||
|
@ -36,7 +36,9 @@
|
||||
#include "../Core/System.h"
|
||||
|
||||
GPUgstate gstate;
|
||||
GPUStateCache gstate_c;
|
||||
GPUInterface *gpu;
|
||||
GPUStatistics gpuStats;
|
||||
|
||||
void InitGfxState()
|
||||
{
|
||||
@ -53,9 +55,9 @@ void InitGfxState()
|
||||
0,0,0,};
|
||||
static const float identity4x4[16] =
|
||||
{1,0,0,0,
|
||||
0,1,0,0,
|
||||
0,0,1,0,
|
||||
0,0,0,1};
|
||||
0,1,0,0,
|
||||
0,0,1,0,
|
||||
0,0,0,1};
|
||||
|
||||
memcpy(gstate.worldMatrix, identity4x3, 12 * sizeof(float));
|
||||
memcpy(gstate.viewMatrix, identity4x3, 12 * sizeof(float));
|
||||
@ -85,9 +87,12 @@ void ShutdownGfxState()
|
||||
// or saved the context and has reloaded it, call this function.
|
||||
void ReapplyGfxState()
|
||||
{
|
||||
if (!gpu)
|
||||
return;
|
||||
// ShaderManager_DirtyShader();
|
||||
// The commands are embedded in the command memory so we can just reexecute the words. Convenient.
|
||||
// To be safe we pass 0xFFFFFFF as the diff.
|
||||
/*
|
||||
gpu->ExecuteOp(gstate.cmdmem[GE_CMD_ALPHABLENDENABLE], 0xFFFFFFFF);
|
||||
gpu->ExecuteOp(gstate.cmdmem[GE_CMD_ALPHATESTENABLE], 0xFFFFFFFF);
|
||||
gpu->ExecuteOp(gstate.cmdmem[GE_CMD_BLENDMODE], 0xFFFFFFFF);
|
||||
@ -97,4 +102,24 @@ void ReapplyGfxState()
|
||||
gpu->ExecuteOp(gstate.cmdmem[GE_CMD_CULLFACEENABLE], 0xFFFFFFFF);
|
||||
gpu->ExecuteOp(gstate.cmdmem[GE_CMD_SCISSOR1], 0xFFFFFFFF);
|
||||
gpu->ExecuteOp(gstate.cmdmem[GE_CMD_SCISSOR2], 0xFFFFFFFF);
|
||||
*/
|
||||
for (int i = GE_CMD_VERTEXTYPE; i < GE_CMD_BONEMATRIXNUMBER; i++)
|
||||
{
|
||||
gpu->ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
// Can't write to bonematrixnumber here
|
||||
|
||||
for (int i = GE_CMD_MORPHWEIGHT0; i < GE_CMD_PATCHFACING; i++)
|
||||
{
|
||||
gpu->ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
// There are a few here in the middle that we shouldn't execute...
|
||||
|
||||
for (int i = GE_CMD_VIEWPORTX1; i < GE_CMD_TRANSFERSTART; i++)
|
||||
{
|
||||
gpu->ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF);
|
||||
}
|
||||
// TODO: there's more...
|
||||
}
|
||||
|
@ -72,8 +72,6 @@ struct Color4
|
||||
|
||||
struct GPUgstate
|
||||
{
|
||||
u16 paletteMem[256*2];
|
||||
|
||||
union
|
||||
{
|
||||
u32 cmdmem[256];
|
||||
@ -230,6 +228,20 @@ struct GPUgstate
|
||||
};
|
||||
};
|
||||
|
||||
float worldMatrix[12];
|
||||
float viewMatrix[12];
|
||||
float projMatrix[16];
|
||||
float tgenMatrix[12];
|
||||
float boneMatrix[8*12];
|
||||
};
|
||||
|
||||
struct GPUStateCache
|
||||
{
|
||||
// Real data in the context ends here
|
||||
// The rest is cached simplified/converted data for fast access.
|
||||
// What we have here still fits into 512 words, but just barely so we should
|
||||
// in the future just recompute the below on an sceGeRestoreContext().
|
||||
|
||||
u32 vertexAddr;
|
||||
u32 indexAddr;
|
||||
|
||||
@ -249,17 +261,22 @@ struct GPUgstate
|
||||
|
||||
u32 curTextureWidth;
|
||||
u32 curTextureHeight;
|
||||
};
|
||||
|
||||
float worldMatrix[12];
|
||||
float viewMatrix[12];
|
||||
float projMatrix[16];
|
||||
float tgenMatrix[12];
|
||||
float boneMatrix[8*12];
|
||||
// TODO: Implement support for these.
|
||||
struct GPUStatistics
|
||||
{
|
||||
// Per frame statistics
|
||||
int numDrawCalls;
|
||||
int numTextureSwitches;
|
||||
int numShaderSwitches;
|
||||
|
||||
// Total statistics
|
||||
int numFrames;
|
||||
};
|
||||
|
||||
void InitGfxState();
|
||||
void ShutdownGfxState();
|
||||
|
||||
void ReapplyGfxState();
|
||||
|
||||
// PSP uses a curious 24-bit float - it's basically the top 24 bits of a regular IEEE754 32-bit float.
|
||||
@ -282,4 +299,6 @@ inline unsigned int toFloat24(float f) {
|
||||
class GPUInterface;
|
||||
|
||||
extern GPUgstate gstate;
|
||||
extern GPUInterface *gpu;
|
||||
extern GPUStateCache gstate_c;
|
||||
extern GPUInterface *gpu;
|
||||
extern GPUStatistics gpuStats;
|
@ -121,13 +121,13 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
break;
|
||||
|
||||
case GE_CMD_VADDR: /// <<8????
|
||||
gstate.vertexAddr = ((gstate.base & 0x00FF0000) << 8)|data;
|
||||
DEBUG_LOG(G3D,"DL VADDR: %06x", gstate.vertexAddr);
|
||||
gstate_c.vertexAddr = ((gstate.base & 0x00FF0000) << 8)|data;
|
||||
DEBUG_LOG(G3D,"DL VADDR: %06x", gstate_c.vertexAddr);
|
||||
break;
|
||||
|
||||
case GE_CMD_IADDR:
|
||||
gstate.indexAddr = ((gstate.base & 0x00FF0000) << 8)|data;
|
||||
DEBUG_LOG(G3D,"DL IADDR: %06x", gstate.indexAddr);
|
||||
gstate_c.indexAddr = ((gstate.base & 0x00FF0000) << 8)|data;
|
||||
DEBUG_LOG(G3D,"DL IADDR: %06x", gstate_c.indexAddr);
|
||||
break;
|
||||
|
||||
case GE_CMD_PRIM:
|
||||
@ -143,7 +143,7 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
"TRIANGLE_FAN=5,",
|
||||
"RECTANGLES=6,",
|
||||
};
|
||||
DEBUG_LOG(G3D, "DL DrawPrim type: %s count: %i vaddr= %08x, iaddr= %08x", type<7 ? types[type] : "INVALID", count, gstate.vertexAddr, gstate.indexAddr);
|
||||
DEBUG_LOG(G3D, "DL DrawPrim type: %s count: %i vaddr= %08x, iaddr= %08x", type<7 ? types[type] : "INVALID", count, gstate_c.vertexAddr, gstate_c.indexAddr);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -200,7 +200,8 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
int behaviour = (data >> 16) & 0xFF;
|
||||
int signal = data & 0xFFFF;
|
||||
|
||||
__TriggerInterruptWithArg(PSP_GE_INTR, PSP_GE_SUBINTR_SIGNAL, signal);
|
||||
if (interruptsEnabled_)
|
||||
__TriggerInterruptWithArg(PSP_GE_INTR, PSP_GE_SUBINTR_SIGNAL, signal);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -230,7 +231,8 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
|
||||
case GE_CMD_FINISH:
|
||||
DEBUG_LOG(G3D,"DL CMD FINISH");
|
||||
__TriggerInterruptWithArg(PSP_GE_INTR, PSP_GE_SUBINTR_FINISH, 0);
|
||||
if (interruptsEnabled_)
|
||||
__TriggerInterruptWithArg(PSP_GE_INTR, PSP_GE_SUBINTR_FINISH, 0);
|
||||
break;
|
||||
|
||||
case GE_CMD_END:
|
||||
@ -248,6 +250,7 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
}
|
||||
|
||||
// This should generate a Reading Ended interrupt
|
||||
// if (interruptsEnabled_)
|
||||
// __TriggerInterrupt(PSP_GE_INTR);
|
||||
|
||||
break;
|
||||
@ -305,23 +308,23 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
break;
|
||||
|
||||
case GE_CMD_TEXSCALEU:
|
||||
gstate.uScale = getFloat24(data);
|
||||
DEBUG_LOG(G3D, "DL Texture U Scale: %f", gstate.uScale);
|
||||
gstate_c.uScale = getFloat24(data);
|
||||
DEBUG_LOG(G3D, "DL Texture U Scale: %f", gstate_c.uScale);
|
||||
break;
|
||||
|
||||
case GE_CMD_TEXSCALEV:
|
||||
gstate.vScale = getFloat24(data);
|
||||
DEBUG_LOG(G3D, "DL Texture V Scale: %f", gstate.vScale);
|
||||
gstate_c.vScale = getFloat24(data);
|
||||
DEBUG_LOG(G3D, "DL Texture V Scale: %f", gstate_c.vScale);
|
||||
break;
|
||||
|
||||
case GE_CMD_TEXOFFSETU:
|
||||
gstate.uOff = getFloat24(data);
|
||||
DEBUG_LOG(G3D, "DL Texture U Offset: %f", gstate.uOff);
|
||||
gstate_c.uOff = getFloat24(data);
|
||||
DEBUG_LOG(G3D, "DL Texture U Offset: %f", gstate_c.uOff);
|
||||
break;
|
||||
|
||||
case GE_CMD_TEXOFFSETV:
|
||||
gstate.vOff = getFloat24(data);
|
||||
DEBUG_LOG(G3D, "DL Texture V Offset: %f", gstate.vOff);
|
||||
gstate_c.vOff = getFloat24(data);
|
||||
DEBUG_LOG(G3D, "DL Texture V Offset: %f", gstate_c.vOff);
|
||||
break;
|
||||
|
||||
case GE_CMD_SCISSOR1:
|
||||
@ -365,7 +368,7 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
break;
|
||||
|
||||
case GE_CMD_TEXADDR0:
|
||||
gstate.textureChanged=true;
|
||||
gstate_c.textureChanged=true;
|
||||
case GE_CMD_TEXADDR1:
|
||||
case GE_CMD_TEXADDR2:
|
||||
case GE_CMD_TEXADDR3:
|
||||
@ -377,7 +380,7 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
break;
|
||||
|
||||
case GE_CMD_TEXBUFWIDTH0:
|
||||
gstate.textureChanged=true;
|
||||
gstate_c.textureChanged=true;
|
||||
case GE_CMD_TEXBUFWIDTH1:
|
||||
case GE_CMD_TEXBUFWIDTH2:
|
||||
case GE_CMD_TEXBUFWIDTH3:
|
||||
@ -397,16 +400,12 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
break;
|
||||
|
||||
case GE_CMD_LOADCLUT:
|
||||
// This could be used to "dirty" textures with clut.
|
||||
{
|
||||
u32 clutAttr = ((gstate.clutaddrupper & 0xFF0000)<<8) | (gstate.clutaddr & 0xFFFFFF);
|
||||
if (clutAttr)
|
||||
u32 clutAddr = ((gstate.clutaddrupper & 0xFF0000)<<8) | (gstate.clutaddr & 0xFFFFFF);
|
||||
if (clutAddr)
|
||||
{
|
||||
u16 *clut = (u16*)Memory::GetPointer(clutAttr);
|
||||
if (clut) {
|
||||
int numColors = 16 * (data&0x3F);
|
||||
memcpy(&gstate.paletteMem[0], clut, numColors * 2);
|
||||
}
|
||||
DEBUG_LOG(G3D,"DL Clut load: %i palettes", data);
|
||||
DEBUG_LOG(G3D,"DL Clut load: %08x", clutAddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -416,7 +415,7 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
}
|
||||
break;
|
||||
|
||||
// case GE_CMD_TRANSFERSRC:
|
||||
//case GE_CMD_TRANSFERSRC:
|
||||
|
||||
case GE_CMD_TRANSFERSRCW:
|
||||
{
|
||||
@ -469,9 +468,9 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
}
|
||||
|
||||
case GE_CMD_TEXSIZE0:
|
||||
gstate.textureChanged=true;
|
||||
gstate.curTextureWidth = 1 << (gstate.texsize[0] & 0xf);
|
||||
gstate.curTextureHeight = 1 << ((gstate.texsize[0]>>8) & 0xf);
|
||||
gstate_c.textureChanged=true;
|
||||
gstate_c.curTextureWidth = 1 << (gstate.texsize[0] & 0xf);
|
||||
gstate_c.curTextureHeight = 1 << ((gstate.texsize[0]>>8) & 0xf);
|
||||
//fall thru - ignoring the mipmap sizes for now
|
||||
case GE_CMD_TEXSIZE1:
|
||||
case GE_CMD_TEXSIZE2:
|
||||
@ -546,7 +545,7 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
int c = n % 3;
|
||||
float val = getFloat24(data);
|
||||
DEBUG_LOG(G3D,"DL Light %i %c pos: %f", l, c+'X', val);
|
||||
gstate.lightpos[l][c] = val;
|
||||
gstate_c.lightpos[l][c] = val;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -560,7 +559,7 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
int c = n % 3;
|
||||
float val = getFloat24(data);
|
||||
DEBUG_LOG(G3D,"DL Light %i %c dir: %f", l, c+'X', val);
|
||||
gstate.lightdir[l][c] = val;
|
||||
gstate_c.lightdir[l][c] = val;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -574,7 +573,7 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
int c = n % 3;
|
||||
float val = getFloat24(data);
|
||||
DEBUG_LOG(G3D,"DL Light %i %c att: %f", l, c+'X', val);
|
||||
gstate.lightatt[l][c] = val;
|
||||
gstate_c.lightatt[l][c] = val;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -589,9 +588,9 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
|
||||
int l = (cmd - GE_CMD_LAC0) / 3;
|
||||
int t = (cmd - GE_CMD_LAC0) % 3;
|
||||
gstate.lightColor[t][l].r = r;
|
||||
gstate.lightColor[t][l].g = g;
|
||||
gstate.lightColor[t][l].b = b;
|
||||
gstate_c.lightColor[t][l].r = r;
|
||||
gstate_c.lightColor[t][l].g = g;
|
||||
gstate_c.lightColor[t][l].b = b;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -618,9 +617,9 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
break;
|
||||
|
||||
case GE_CMD_PATCHDIVISION:
|
||||
gstate.patch_div_s = data & 0xFF;
|
||||
gstate.patch_div_t = (data >> 8) & 0xFF;
|
||||
DEBUG_LOG(G3D, "DL Patch subdivision: %i x %i", gstate.patch_div_s, gstate.patch_div_t);
|
||||
gstate_c.patch_div_s = data & 0xFF;
|
||||
gstate_c.patch_div_t = (data >> 8) & 0xFF;
|
||||
DEBUG_LOG(G3D, "DL Patch subdivision: %i x %i", gstate_c.patch_div_s, gstate_c.patch_div_t);
|
||||
break;
|
||||
|
||||
case GE_CMD_MATERIALUPDATE:
|
||||
@ -731,7 +730,7 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
int index = cmd - GE_CMD_MORPHWEIGHT0;
|
||||
float weight = getFloat24(data);
|
||||
DEBUG_LOG(G3D,"DL MorphWeight %i = %f", index, weight);
|
||||
gstate.morphWeights[index] = weight;
|
||||
gstate_c.morphWeights[index] = weight;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -24,11 +24,17 @@ class ShaderManager;
|
||||
class NullGPU : public GPUInterface
|
||||
{
|
||||
public:
|
||||
NullGPU() : interruptsEnabled_(true) {}
|
||||
virtual void InitClear() {}
|
||||
virtual u32 EnqueueList(u32 listpc, u32 stall);
|
||||
virtual void UpdateStall(int listid, u32 newstall);
|
||||
virtual void ExecuteOp(u32 op, u32 diff);
|
||||
virtual bool InterpretList();
|
||||
virtual void DrawSync(int mode);
|
||||
virtual void EnableInterrupts(bool enable) {
|
||||
interruptsEnabled_ = enable;
|
||||
}
|
||||
private:
|
||||
bool ProcessDLQueue();
|
||||
bool interruptsEnabled_;
|
||||
};
|
||||
|
@ -1 +1,2 @@
|
||||
cp -r ../android/assets .
|
||||
cp ../ppge_atlas.zim assets
|
||||
|
@ -89,6 +89,10 @@
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>..\</OutDir>
|
||||
<TargetName>PPSSPPDebug</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
@ -105,7 +109,6 @@
|
||||
<Link>
|
||||
<AdditionalDependencies>XInput.lib;Winmm.lib;Ws2_32.lib;opengl32.lib;glu32.lib;comctl32.lib;dsound.lib;xinput.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(OutDir)$(ProjectName).pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
|
BIN
android/assets/ppge_atlas.zim
Normal file
BIN
android/assets/ppge_atlas.zim
Normal file
Binary file not shown.
@ -1,5 +1,6 @@
|
||||
mkdir -p assets
|
||||
./buildatlas.sh
|
||||
cp ../ppge_atlas.zim assets
|
||||
#cp -r source_assets/songs assets
|
||||
#cp -r source_assets/samples assets
|
||||
#cp -r ../shaders assets
|
||||
|
@ -63,6 +63,7 @@ LOCAL_SRC_FILES := \
|
||||
$(SRC)/Common/IniFile.cpp \
|
||||
$(SRC)/Common/FileUtil.cpp \
|
||||
$(SRC)/Common/StringUtil.cpp \
|
||||
$(SRC)/Common/Thread.cpp \
|
||||
$(SRC)/Common/Timer.cpp \
|
||||
$(SRC)/Common/ThunkARM.cpp \
|
||||
$(SRC)/Common/Misc.cpp \
|
||||
@ -150,7 +151,9 @@ LOCAL_SRC_FILES := \
|
||||
$(SRC)/Core/MIPS/ARM/Jit.cpp \
|
||||
$(SRC)/Core/MIPS/ARM/CompLoadStore.cpp \
|
||||
$(SRC)/Core/MIPS/ARM/RegCache.cpp \
|
||||
$(SRC)/Core/Util/BlockAllocator.cpp
|
||||
$(SRC)/Core/Util/BlockAllocator.cpp \
|
||||
$(SRC)/Core/Util/ppge_atlas.cpp \
|
||||
$(SRC)/Core/Util/PPGeDraw.cpp
|
||||
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
1
build_ppgeatlas.sh
Normal file
1
build_ppgeatlas.sh
Normal file
@ -0,0 +1 @@
|
||||
native/tools/build/atlastool ppge_atlasscript.txt ppge && mv ppge_atlas.cpp ppge_atlas.h Core/Util
|
2
main.cpp
2
main.cpp
@ -56,7 +56,7 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
|
||||
token = strtok(szCmdLine," ");
|
||||
|
||||
g_Config.Load();
|
||||
VFSRegister("", new DirectoryAssetReader("shaders"));
|
||||
VFSRegister("", new DirectoryAssetReader(""));
|
||||
|
||||
while (token)
|
||||
{
|
||||
|
BIN
ppge_atlas.zim
Normal file
BIN
ppge_atlas.zim
Normal file
Binary file not shown.
8
ppge_atlasscript.txt
Normal file
8
ppge_atlasscript.txt
Normal file
@ -0,0 +1,8 @@
|
||||
256
|
||||
font UBUNTU24 android/source_assets/font/zrnic.ttf 30
|
||||
image I_CROSS android/source_assets/image/cross.png copy
|
||||
image I_CIRCLE android/source_assets/image/circle.png copy
|
||||
image I_SQUARE android/source_assets/image/square.png copy
|
||||
image I_TRIANGLE android/source_assets/image/triangle.png copy
|
||||
image I_BUTTON android/source_assets/image/button.png copy
|
||||
image I_LOGO android/res/drawable-mdpi/ic_launcher.png copy
|
Loading…
Reference in New Issue
Block a user