mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #6765 from hrydgard/thin3d
Switch UI drawing from GL to Thin3D. This activates the D3D9 path as well.
This commit is contained in:
commit
5d836bfa5a
50 changed files with 614 additions and 629 deletions
|
@ -762,7 +762,6 @@ set(NativeAppSource
|
|||
UI/TouchControlLayoutScreen.cpp
|
||||
UI/TouchControlVisibilityScreen.cpp
|
||||
UI/GamepadEmu.cpp
|
||||
UI/UIShader.cpp
|
||||
UI/OnScreenDisplay.cpp
|
||||
UI/ControlMappingScreen.cpp
|
||||
UI/Store.cpp
|
||||
|
@ -897,6 +896,9 @@ add_library(native STATIC
|
|||
native/net/url.h
|
||||
native/profiler/profiler.cpp
|
||||
native/profiler/profiler.h
|
||||
native/thin3d/thin3d.cpp
|
||||
native/thin3d/thin3d.h
|
||||
native/thin3d/thin3d_gl.cpp
|
||||
native/thread/prioritizedworkqueue.cpp
|
||||
native/thread/prioritizedworkqueue.h
|
||||
native/thread/threadutil.cpp
|
||||
|
|
|
@ -747,7 +747,7 @@ bool KeyFromPspButton(int btn, std::vector<KeyDef> *keys) {
|
|||
|
||||
bool AxisToPspButton(int deviceId, int axisId, int direction, std::vector<int> *pspKeys) {
|
||||
int key = TranslateKeyCodeFromAxis(axisId, direction);
|
||||
return KeyToPspButton(deviceId, key, pspKeys);
|
||||
return KeyToPspButton(deviceId, key, pspKeys);
|
||||
}
|
||||
|
||||
bool AxisFromPspButton(int btn, int *deviceId, int *axisId, int *direction) {
|
||||
|
|
|
@ -386,6 +386,7 @@ static int DefaultAndroidHwScale() {
|
|||
|
||||
static ConfigSetting graphicsSettings[] = {
|
||||
ConfigSetting("ShowFPSCounter", &g_Config.iShowFPSCounter, 0),
|
||||
ReportedConfigSetting("GPUBackend", &g_Config.iGPUBackend, 0),
|
||||
ReportedConfigSetting("RenderingMode", &g_Config.iRenderingMode, &DefaultRenderingMode),
|
||||
ConfigSetting("SoftwareRendering", &g_Config.bSoftwareRendering, false),
|
||||
ReportedConfigSetting("HardwareTransform", &g_Config.bHardwareTransform, true),
|
||||
|
@ -1060,5 +1061,3 @@ void Config::GetReportingInfo(UrlEncoder &data) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -39,6 +39,12 @@ enum {
|
|||
ROTATION_LOCKED_VERTICAL180 = 4,
|
||||
};
|
||||
|
||||
// Software is not among these because it will have one of these perform the blit to display.
|
||||
enum {
|
||||
GPU_BACKEND_OPENGL = 0,
|
||||
GPU_BACKEND_DIRECT3D9 = 1,
|
||||
};
|
||||
|
||||
namespace http {
|
||||
class Download;
|
||||
class Downloader;
|
||||
|
@ -101,8 +107,8 @@ public:
|
|||
std::vector<std::string> vPinnedPaths;
|
||||
std::string sLanguageIni;
|
||||
|
||||
|
||||
// GFX
|
||||
int iGPUBackend;
|
||||
bool bSoftwareRendering;
|
||||
bool bHardwareTransform; // only used in the GLES backend
|
||||
bool bSoftwareSkinning; // may speed up some games
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#ifdef _WIN32
|
||||
#ifndef _XBOX
|
||||
#include "Windows/OpenGLBase.h"
|
||||
#include "Windows/D3D9Base.h"
|
||||
#endif
|
||||
#include "Windows/InputDevice.h"
|
||||
#endif
|
||||
|
@ -151,6 +152,21 @@ void UpdateRunLoop() {
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(USING_WIN_UI)
|
||||
|
||||
void GPU_SwapBuffers() {
|
||||
switch (g_Config.iGPUBackend) {
|
||||
case GPU_BACKEND_OPENGL:
|
||||
GL_SwapBuffers();
|
||||
break;
|
||||
case GPU_BACKEND_DIRECT3D9:
|
||||
D3D9_SwapBuffers();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Core_RunLoop() {
|
||||
while ((GetUIState() != UISTATE_INGAME || !PSP_IsInited()) && GetUIState() != UISTATE_EXIT) {
|
||||
time_update();
|
||||
|
@ -165,7 +181,7 @@ void Core_RunLoop() {
|
|||
if (sleepTime > 0)
|
||||
Sleep(sleepTime);
|
||||
if (!windowHidden) {
|
||||
GL_SwapBuffers();
|
||||
GPU_SwapBuffers();
|
||||
}
|
||||
#else
|
||||
UpdateRunLoop();
|
||||
|
@ -177,7 +193,7 @@ void Core_RunLoop() {
|
|||
UpdateRunLoop();
|
||||
#if defined(USING_WIN_UI)
|
||||
if (!windowHidden && !Core_IsStepping()) {
|
||||
GL_SwapBuffers();
|
||||
GPU_SwapBuffers();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -185,6 +185,7 @@ void SaveFileInfo::DoState(PointerWrap &p)
|
|||
p.Do(hasTexture);
|
||||
if (hasTexture) {
|
||||
if (p.mode == p.MODE_READ) {
|
||||
delete texture;
|
||||
texture = new PPGeImage("");
|
||||
}
|
||||
texture->DoState(p);
|
||||
|
|
|
@ -1670,15 +1670,15 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr)
|
|||
if (optionAddr) {
|
||||
lmoption = (SceKernelLMOption *)Memory::GetPointer(optionAddr);
|
||||
if (lmoption->position < PSP_SMEM_Low || lmoption->position > PSP_SMEM_HighAligned) {
|
||||
ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position", name, lmoption->position);
|
||||
ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position (%i)", name, (int)lmoption->position);
|
||||
return SCE_KERNEL_ERROR_ILLEGAL_MEMBLOCKTYPE;
|
||||
}
|
||||
if (lmoption->position == PSP_SMEM_LowAligned || lmoption->position == PSP_SMEM_HighAligned) {
|
||||
ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position (aligned)", name, lmoption->position);
|
||||
ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position (aligned)", name);
|
||||
return SCE_KERNEL_ERROR_ILLEGAL_ALIGNMENT_SIZE;
|
||||
}
|
||||
if (lmoption->position == PSP_SMEM_Addr) {
|
||||
ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position (fixed)", name, lmoption->position);
|
||||
ERROR_LOG_REPORT(LOADER, "sceKernelLoadModule(%s): invalid position (fixed)", name);
|
||||
return SCE_KERNEL_ERROR_MEMBLOCK_ALLOC_FAILED;
|
||||
}
|
||||
WARN_LOG_REPORT(LOADER, "sceKernelLoadModule: unsupported options size=%08x, flags=%08x, pos=%d, access=%d, data=%d, text=%d", lmoption->size, lmoption->flags, lmoption->position, lmoption->access, lmoption->mpiddata, lmoption->mpidtext);
|
||||
|
|
|
@ -316,7 +316,7 @@ MIPSOpcode JitBlockCache::GetEmuHackOpForBlock(int blockNum) const {
|
|||
}
|
||||
|
||||
int JitBlockCache::GetBlockNumberFromStartAddress(u32 addr, bool realBlocksOnly) {
|
||||
if (!blocks_)
|
||||
if (!blocks_ || !Memory::IsValidAddress(addr))
|
||||
return -1;
|
||||
|
||||
MIPSOpcode inst = MIPSOpcode(Memory::Read_U32(addr));
|
||||
|
|
|
@ -241,19 +241,6 @@ void FramebufferManagerDX9::DrawPixels(const u8 *framebuf, GEBufferFormat pixelF
|
|||
DrawActiveTexture(x, y, w, h, false, 480.0f / 512.0f);
|
||||
}
|
||||
|
||||
// Depth in ogl is between -1;1 we need between 0;1
|
||||
static void ConvertMatrices(Matrix4x4 & in) {
|
||||
/*
|
||||
in.zz *= 0.5f;
|
||||
in.wz += 1.f;
|
||||
*/
|
||||
Matrix4x4 s;
|
||||
Matrix4x4 t;
|
||||
s.setScaling(Vec3(1, 1, 0.5f));
|
||||
t.setTranslation(Vec3(0, 0, 0.5f));
|
||||
in = in * s;
|
||||
in = in * t;
|
||||
}
|
||||
|
||||
void FramebufferManagerDX9::DrawActiveTexture(float x, float y, float w, float h, bool flip, float uscale, float vscale) {
|
||||
float u2 = uscale;
|
||||
|
@ -269,9 +256,9 @@ void FramebufferManagerDX9::DrawActiveTexture(float x, float y, float w, float h
|
|||
};
|
||||
|
||||
Matrix4x4 ortho;
|
||||
ConvertMatrices(ortho);
|
||||
|
||||
ortho.setOrtho(0, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, 0, -1, 1);
|
||||
ConvertProjMatrixToD3D(ortho);
|
||||
|
||||
//pD3Ddevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
|
||||
pD3Ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
|
@ -635,6 +622,7 @@ void FramebufferManagerDX9::CopyDisplayToOutput() {
|
|||
dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight);
|
||||
DEBUG_LOG(SCEGE, "Displaying FBO %08x", vfb->fb_address);
|
||||
DisableState();
|
||||
|
||||
fbo_bind_color_as_texture(vfb->fbo, 0);
|
||||
|
||||
// These are in the output display coordinates
|
||||
|
|
|
@ -268,26 +268,17 @@ void LinkedShaderDX9::SetColorUniform3ExtraFloat(D3DXHANDLE uniform, u32 color,
|
|||
void LinkedShaderDX9::SetMatrix4x3(D3DXHANDLE uniform, const float *m4x3) {
|
||||
float m4x4[16];
|
||||
ConvertMatrix4x3To4x4(m4x4, m4x3);
|
||||
|
||||
if (m_vs->constant->SetMatrix(pD3Ddevice, uniform, (D3DXMATRIX*)m4x4) == D3D_OK);
|
||||
else
|
||||
m_fs->constant->SetMatrix(pD3Ddevice, uniform, (D3DXMATRIX*)m4x4);
|
||||
m_vs->constant->SetMatrix(pD3Ddevice, uniform, (D3DXMATRIX*)m4x4);
|
||||
}
|
||||
|
||||
void LinkedShaderDX9::SetMatrix(D3DXHANDLE uniform, const float* pMatrix) {
|
||||
D3DXMATRIX * pDxMat = (D3DXMATRIX*)pMatrix;
|
||||
|
||||
if (m_vs->constant->SetMatrix(pD3Ddevice, uniform, pDxMat) == D3D_OK);
|
||||
else
|
||||
m_fs->constant->SetMatrix(pD3Ddevice, uniform, pDxMat);
|
||||
m_vs->constant->SetMatrix(pD3Ddevice, uniform, pDxMat);
|
||||
}
|
||||
|
||||
// Depth in ogl is between -1;1 we need between 0;1
|
||||
static void ConvertMatrices(Matrix4x4 & in) {
|
||||
/*
|
||||
in.zz *= 0.5f;
|
||||
in.wz += 1.f;
|
||||
*/
|
||||
// Pretty sure this is wrong, our Z buffer is screwed up anyhow..
|
||||
void ConvertProjMatrixToD3D(Matrix4x4 & in) {
|
||||
Matrix4x4 s;
|
||||
Matrix4x4 t;
|
||||
s.setScaling(Vec3(1, 1, 0.5f));
|
||||
|
@ -297,7 +288,6 @@ static void ConvertMatrices(Matrix4x4 & in) {
|
|||
}
|
||||
|
||||
void LinkedShaderDX9::use() {
|
||||
|
||||
updateUniforms();
|
||||
|
||||
pD3Ddevice->SetPixelShader(m_fs->shader);
|
||||
|
@ -325,7 +315,7 @@ void LinkedShaderDX9::updateUniforms() {
|
|||
flippedMatrix[12] = -flippedMatrix[12];
|
||||
}
|
||||
// Convert matrices !
|
||||
ConvertMatrices(flippedMatrix);
|
||||
ConvertProjMatrixToD3D(flippedMatrix);
|
||||
|
||||
SetMatrix(u_proj, flippedMatrix.getReadPtr());
|
||||
}
|
||||
|
@ -335,7 +325,7 @@ void LinkedShaderDX9::updateUniforms() {
|
|||
proj_through.setOrtho(0.0f, gstate_c.curRTWidth, gstate_c.curRTHeight, 0, 0, 1);
|
||||
|
||||
// Convert matrices !
|
||||
ConvertMatrices(proj_through);
|
||||
ConvertProjMatrixToD3D(proj_through);
|
||||
|
||||
SetMatrix(u_proj_through, proj_through.getReadPtr());
|
||||
}
|
||||
|
|
|
@ -22,11 +22,14 @@
|
|||
#include <map>
|
||||
#include "GPU/Directx9/VertexShaderGeneratorDX9.h"
|
||||
#include "GPU/Directx9/PixelShaderGeneratorDX9.h"
|
||||
#include "thin3d/d3dx9_loader.h"
|
||||
#include "math/lin/matrix4x4.h"
|
||||
|
||||
namespace DX9 {
|
||||
|
||||
class PSShader;
|
||||
class VSShader;
|
||||
void ConvertProjMatrixToD3D(Matrix4x4 & in);
|
||||
|
||||
class LinkedShaderDX9
|
||||
{
|
||||
|
|
|
@ -77,6 +77,11 @@ static const D3DCMPFUNC ztests[] = {
|
|||
D3DCMP_LESS, D3DCMP_LESSEQUAL, D3DCMP_GREATER, D3DCMP_GREATEREQUAL,
|
||||
};
|
||||
|
||||
static const D3DCMPFUNC ztests_backwards[] = {
|
||||
D3DCMP_NEVER, D3DCMP_ALWAYS, D3DCMP_EQUAL, D3DCMP_NOTEQUAL,
|
||||
D3DCMP_GREATER, D3DCMP_GREATEREQUAL, D3DCMP_LESS, D3DCMP_LESSEQUAL,
|
||||
};
|
||||
|
||||
static const D3DSTENCILOP stencilOps[] = {
|
||||
D3DSTENCILOP_KEEP,
|
||||
D3DSTENCILOP_ZERO,
|
||||
|
@ -192,8 +197,8 @@ void TransformDrawEngineDX9::ApplyDrawState(int prim) {
|
|||
}
|
||||
|
||||
// At this point, through all paths above, glBlendFuncA and glBlendFuncB will be set right somehow.
|
||||
dxstate.blendFunc.set(glBlendFuncA, glBlendFuncB);
|
||||
dxstate.blendEquation.set(eqLookup[blendFuncEq]);
|
||||
dxstate.blendFunc.set(glBlendFuncA, glBlendFuncB, D3DBLEND_ONE, D3DBLEND_ZERO);
|
||||
dxstate.blendEquation.set(eqLookup[blendFuncEq], D3DBLENDOP_ADD);
|
||||
}
|
||||
|
||||
// Set Dither
|
||||
|
@ -229,7 +234,6 @@ void TransformDrawEngineDX9::ApplyDrawState(int prim) {
|
|||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Set cull
|
||||
bool wantCull = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled();
|
||||
dxstate.cullMode.set(wantCull, gstate.getCullMode());
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "GPU/GPUState.h"
|
||||
#include "GPU/Directx9/TextureCacheDX9.h"
|
||||
#include "GPU/Directx9/FramebufferDX9.h"
|
||||
#include "GPU/Directx9/helper/dx_state.h"
|
||||
#include "GPU/Common/TextureDecoder.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/Host.h"
|
||||
|
@ -32,6 +33,7 @@
|
|||
#include "ext/xxhash.h"
|
||||
#include "math/math_util.h"
|
||||
|
||||
|
||||
extern int g_iNumVideos;
|
||||
|
||||
namespace DX9 {
|
||||
|
@ -75,12 +77,14 @@ void TextureCacheDX9::Clear(bool delete_them) {
|
|||
lastBoundTexture = INVALID_TEX;
|
||||
if (delete_them) {
|
||||
for (TexCache::iterator iter = cache.begin(); iter != cache.end(); ++iter) {
|
||||
DEBUG_LOG(G3D, "Deleting texture %i", iter->second.texture);
|
||||
iter->second.texture->Release();
|
||||
DEBUG_LOG(G3D, "Deleting texture %p", iter->second.texture);
|
||||
if (iter->second.texture)
|
||||
iter->second.texture->Release();
|
||||
}
|
||||
for (TexCache::iterator iter = secondCache.begin(); iter != secondCache.end(); ++iter) {
|
||||
DEBUG_LOG(G3D, "Deleting texture %i", iter->second.texture);
|
||||
iter->second.texture->Release();
|
||||
DEBUG_LOG(G3D, "Deleting texture %p", iter->second.texture);
|
||||
if (iter->second.texture)
|
||||
iter->second.texture->Release();
|
||||
}
|
||||
}
|
||||
if (cache.size() + secondCache.size()) {
|
||||
|
@ -103,7 +107,8 @@ void TextureCacheDX9::Decimate() {
|
|||
int killAge = lowMemoryMode_ ? TEXTURE_KILL_AGE_LOWMEM : TEXTURE_KILL_AGE;
|
||||
for (TexCache::iterator iter = cache.begin(); iter != cache.end(); ) {
|
||||
if (iter->second.lastFrame + killAge < gpuStats.numFlips) {
|
||||
iter->second.texture->Release();
|
||||
if (iter->second.texture)
|
||||
iter->second.texture->Release();
|
||||
cache.erase(iter++);
|
||||
} else {
|
||||
++iter;
|
||||
|
@ -114,7 +119,8 @@ void TextureCacheDX9::Decimate() {
|
|||
for (TexCache::iterator iter = secondCache.begin(); iter != secondCache.end(); ) {
|
||||
// In low memory mode, we kill them all.
|
||||
if (lowMemoryMode_ || iter->second.lastFrame + TEXTURE_KILL_AGE < gpuStats.numFlips) {
|
||||
iter->second.texture->Release();
|
||||
if (iter->second.texture)
|
||||
iter->second.texture->Release();
|
||||
secondCache.erase(iter++);
|
||||
} else {
|
||||
++iter;
|
||||
|
@ -451,7 +457,7 @@ D3DFORMAT getClutDestFormat(GEPaletteFormat format) {
|
|||
|
||||
static const u8 texByteAlignMap[] = {2, 2, 2, 4};
|
||||
|
||||
static const u32 MinFilt[8] = {
|
||||
static const u8 MinFilt[8] = {
|
||||
D3DTEXF_POINT,
|
||||
D3DTEXF_LINEAR,
|
||||
D3DTEXF_POINT,
|
||||
|
@ -462,7 +468,7 @@ static const u32 MinFilt[8] = {
|
|||
D3DTEXF_LINEAR, // GL_LINEAR_MIPMAP_LINEAR,
|
||||
};
|
||||
|
||||
static const u32 MipFilt[8] = {
|
||||
static const u8 MipFilt[8] = {
|
||||
D3DTEXF_POINT,
|
||||
D3DTEXF_LINEAR,
|
||||
D3DTEXF_POINT,
|
||||
|
@ -473,13 +479,11 @@ static const u32 MipFilt[8] = {
|
|||
D3DTEXF_LINEAR, // GL_LINEAR_MIPMAP_LINEAR,
|
||||
};
|
||||
|
||||
static const u32 MagFilt[2] = {
|
||||
static const u8 MagFilt[2] = {
|
||||
D3DTEXF_POINT,
|
||||
D3DTEXF_LINEAR
|
||||
};
|
||||
|
||||
// This should not have to be done per texture! OpenGL is silly yo
|
||||
// TODO: Dirty-check this against the current texture.
|
||||
void TextureCacheDX9::UpdateSamplingParams(TexCacheEntry &entry, bool force) {
|
||||
int minFilt = gstate.texfilter & 0x7;
|
||||
int magFilt = (gstate.texfilter>>8) & 1;
|
||||
|
@ -517,23 +521,11 @@ void TextureCacheDX9::UpdateSamplingParams(TexCacheEntry &entry, bool force) {
|
|||
minFilt &= 1;
|
||||
}
|
||||
|
||||
if (force || entry.minFilt != minFilt) {
|
||||
pD3Ddevice->SetSamplerState(0, D3DSAMP_MINFILTER, MinFilt[minFilt]);
|
||||
pD3Ddevice->SetSamplerState(0, D3DSAMP_MIPFILTER, MipFilt[minFilt]);
|
||||
entry.minFilt = minFilt;
|
||||
}
|
||||
if (force || entry.magFilt != magFilt) {
|
||||
pD3Ddevice->SetSamplerState(0, D3DSAMP_MAGFILTER, MagFilt[magFilt]);
|
||||
entry.magFilt = magFilt;
|
||||
}
|
||||
if (force || entry.sClamp != sClamp) {
|
||||
pD3Ddevice->SetSamplerState(0, D3DSAMP_ADDRESSU, sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
|
||||
entry.sClamp = sClamp;
|
||||
}
|
||||
if (force || entry.tClamp != tClamp) {
|
||||
pD3Ddevice->SetSamplerState(0, D3DSAMP_ADDRESSV, tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
|
||||
entry.tClamp = tClamp;
|
||||
}
|
||||
dxstate.texMinFilter.set(MinFilt[minFilt]);
|
||||
dxstate.texMipFilter.set(MipFilt[minFilt]);
|
||||
dxstate.texMagFilter.set(MagFilt[magFilt]);
|
||||
dxstate.texAddressU.set(sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
|
||||
dxstate.texAddressV.set(tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP);
|
||||
|
||||
#ifdef _XBOX
|
||||
pD3Ddevice->SetRenderState(D3DRS_HALFPIXELOFFSET, TRUE );
|
||||
|
@ -569,9 +561,8 @@ static void ClutConvertColors(void *dstBuf, const void *srcBuf, u32 dstFmt, int
|
|||
const u16_le *src = (const u16_le *)srcBuf;
|
||||
u16_le *dst = (u16_le *)dstBuf;
|
||||
for (int i = 0; i < numPixels; i++) {
|
||||
// Already good format
|
||||
u16 rgb = src[i];
|
||||
dst[i] = (rgb & 0xF) | (rgb & 0xF0)<<8 | ( rgb & 0xF00) | ((rgb & 0xF000)>>8);
|
||||
dst[i] = ((rgb & 0xF) << 8) | (rgb & 0xF0F0) | ((rgb & 0xF00) >> 8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -581,7 +572,7 @@ static void ClutConvertColors(void *dstBuf, const void *srcBuf, u32 dstFmt, int
|
|||
u16 *dst = (u16 *)dstBuf;
|
||||
for (int i = 0; i < numPixels; i++) {
|
||||
u16 rgb = src[i];
|
||||
dst[i] = ((rgb & 0x1f) << 11) | ( rgb & 0x7e0) | ((rgb & 0xF800) >>11 );
|
||||
dst[i] = ((rgb & 0x1f) << 11) | (rgb & 0x7e0) | ((rgb & 0xF800) >> 11);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -721,12 +712,12 @@ void TextureCacheDX9::UpdateCurrentClut() {
|
|||
clutAlphaLinear_ = true;
|
||||
clutAlphaLinearColor_ = clut[15] & 0xFFF0;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
if ((clut[i] & 0xf) != i) {
|
||||
if ((clut[i] >> 12) != i) {
|
||||
clutAlphaLinear_ = false;
|
||||
break;
|
||||
}
|
||||
// Alpha 0 doesn't matter.
|
||||
if (i != 0 && (clut[i] & 0xFFF0) != clutAlphaLinearColor_) {
|
||||
if (i != 0 && (clut[i] >> 12) != clutAlphaLinearColor_) {
|
||||
clutAlphaLinear_ = false;
|
||||
break;
|
||||
}
|
||||
|
@ -745,48 +736,6 @@ inline u32 TextureCacheDX9::GetCurrentClutHash() {
|
|||
return clutHash_;
|
||||
}
|
||||
|
||||
// #define DEBUG_TEXTURES
|
||||
|
||||
#ifdef DEBUG_TEXTURES
|
||||
bool SetDebugTexture() {
|
||||
static const int highlightFrames = 30;
|
||||
|
||||
static int numTextures = 0;
|
||||
static int lastFrames = 0;
|
||||
static int mostTextures = 1;
|
||||
|
||||
if (lastFrames != gpuStats.numFlips) {
|
||||
mostTextures = std::max(mostTextures, numTextures);
|
||||
numTextures = 0;
|
||||
lastFrames = gpuStats.numFlips;
|
||||
}
|
||||
|
||||
static GLuint solidTexture = 0;
|
||||
|
||||
bool changed = false;
|
||||
if (((gpuStats.numFlips / highlightFrames) % mostTextures) == numTextures) {
|
||||
if (gpuStats.numFlips % highlightFrames == 0) {
|
||||
NOTICE_LOG(G3D, "Highlighting texture # %d / %d", numTextures, mostTextures);
|
||||
}
|
||||
static const u32 solidTextureData[] = {0x99AA99FF};
|
||||
|
||||
if (solidTexture == 0) {
|
||||
glGenTextures(1, &solidTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, solidTexture);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, solidTextureData);
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, solidTexture);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
||||
++numTextures;
|
||||
return changed;
|
||||
}
|
||||
#endif
|
||||
|
||||
void TextureCacheDX9::SetTextureFramebuffer(TexCacheEntry *entry)
|
||||
{
|
||||
entry->framebuffer->usageFlags |= FB_USAGE_TEXTURE;
|
||||
|
@ -1347,21 +1296,12 @@ void TextureCacheDX9::CheckAlpha(TexCacheEntry &entry, u32 *pixelData, u32 dstFm
|
|||
{
|
||||
const u32 *p = pixelData;
|
||||
for (int i = 0; i < (w * h + 1) / 2; ++i) {
|
||||
#ifndef BIG_ENDIAN
|
||||
u32 a = p[i] & 0x000F000F;
|
||||
hitZeroAlpha |= a ^ 0x000F000F;
|
||||
if (a != 0x000F000F && a != 0x0000000F && a != 0x000F0000 && a != 0) {
|
||||
hitSomeAlpha = 1;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
u32 a = p[i] & 0xF000F000;
|
||||
hitZeroAlpha |= a ^ 0xF000F000;
|
||||
if (a != 0xF000F000 && a != 0x0000F000 && a != 0xF0000000 && a != 0) {
|
||||
hitSomeAlpha = 1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1369,13 +1309,8 @@ void TextureCacheDX9::CheckAlpha(TexCacheEntry &entry, u32 *pixelData, u32 dstFm
|
|||
{
|
||||
const u32 *p = pixelData;
|
||||
for (int i = 0; i < (w * h + 1) / 2; ++i) {
|
||||
#ifndef BIG_ENDIAN
|
||||
u32 a = p[i] & 0x00010001;
|
||||
hitZeroAlpha |= a ^ 0x00010001;
|
||||
#else
|
||||
u32 a = p[i] & 0x10001000;
|
||||
hitZeroAlpha |= a ^ 0x10001000;
|
||||
#endif
|
||||
u32 a = p[i] & 0x80008000;
|
||||
hitZeroAlpha |= a ^ 0x80008000;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1409,12 +1344,13 @@ void TextureCacheDX9::CheckAlpha(TexCacheEntry &entry, u32 *pixelData, u32 dstFm
|
|||
|
||||
static inline void copyTexture(int xoffset, int yoffset, int w, int h, int pitch, int srcfmt, int fmt, void * pSrc, void * pDst) {
|
||||
// Swap color
|
||||
int y;
|
||||
switch(fmt) {
|
||||
case D3DFMT_R5G6B5:
|
||||
case D3DFMT_A4R4G4B4:
|
||||
case D3DFMT_A1R5G5B5:
|
||||
// Really needed ?
|
||||
for(int y = 0; y < h; y++) {
|
||||
for(y = 0; y < h; y++) {
|
||||
const u16 *src = (const u16 *)((u8*)pSrc + (w*2) * y);
|
||||
u16 *dst = (u16*)((u8*)pDst + pitch * y);
|
||||
memcpy(dst, src, w * sizeof(u16));
|
||||
|
@ -1423,23 +1359,13 @@ static inline void copyTexture(int xoffset, int yoffset, int w, int h, int pitch
|
|||
|
||||
// 32 bit texture
|
||||
case D3DFMT_A8R8G8B8:
|
||||
for(int y = 0; y < h; y++) {
|
||||
for(y = 0; y < h; y++) {
|
||||
const u32 *src = (const u32 *)((u8*)pSrc + (w*4) * y);
|
||||
u32 *dst = (u32*)((u8*)pDst + pitch * y);
|
||||
|
||||
/*
|
||||
// todo use memcpy
|
||||
for(int x = 0; x < w; x++) {
|
||||
unsigned int rgb = src[x];
|
||||
dst[x] = rgb;
|
||||
}
|
||||
*/
|
||||
memcpy(dst, src, w * sizeof(u32));
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, int level, bool replaceImages) {
|
||||
|
@ -1494,48 +1420,24 @@ void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, int level, bool rep
|
|||
} else {
|
||||
// Create texture
|
||||
#ifdef _XBOX
|
||||
pD3Ddevice->CreateTexture(w, h, 1, 0, (D3DFORMAT)D3DFMT(dstFmt), NULL, &entry.texture, NULL);
|
||||
HRESULT hr = pD3Ddevice->CreateTexture(w, h, 1, 0, (D3DFORMAT)D3DFMT(dstFmt), NULL, &entry.texture, NULL);
|
||||
#else
|
||||
pD3Ddevice->CreateTexture(w, h, 1, 0, (D3DFORMAT)D3DFMT(dstFmt), D3DPOOL_MANAGED, &entry.texture, NULL);
|
||||
HRESULT hr = pD3Ddevice->CreateTexture(w, h, 1, 0, (D3DFORMAT)D3DFMT(dstFmt), D3DPOOL_MANAGED, &entry.texture, NULL);
|
||||
#endif
|
||||
D3DLOCKED_RECT rect;
|
||||
entry.texture->LockRect(level, &rect, NULL, 0);
|
||||
if (FAILED(hr)) {
|
||||
INFO_LOG(G3D, "Failed to create D3D texture");
|
||||
} else {
|
||||
D3DLOCKED_RECT rect;
|
||||
entry.texture->LockRect(level, &rect, NULL, 0);
|
||||
|
||||
copyTexture(0, 0, w, h, rect.Pitch, entry.format, dstFmt, pixelData, rect.pBits);
|
||||
copyTexture(0, 0, w, h, rect.Pitch, entry.format, dstFmt, pixelData, rect.pBits);
|
||||
|
||||
entry.texture->UnlockRect(level);
|
||||
entry.texture->UnlockRect(level);
|
||||
}
|
||||
}
|
||||
|
||||
//#ifdef _DEBUG
|
||||
#if 0
|
||||
// Hack save to disk ...
|
||||
char fname[256];
|
||||
int fmt = 0;
|
||||
static int ipic = 0;
|
||||
switch(dstFmt) {
|
||||
case D3DFMT_A4R4G4B4:
|
||||
fmt = 0x4444;
|
||||
break;
|
||||
case D3DFMT_A1R5G5B5:
|
||||
fmt = 0x5551;
|
||||
break;
|
||||
case D3DFMT_R5G6B5:
|
||||
fmt = 0x5650;
|
||||
break;
|
||||
case D3DFMT_A8R8G8B8:
|
||||
fmt = 0x8888;
|
||||
break;
|
||||
default:
|
||||
fmt = 0xDEAD;
|
||||
break;
|
||||
}
|
||||
sprintf(fname, "game:\\pic\\pic.%02x.%04x.%08x.%08x.png", ipic++, fmt, entry.format, clutformat);
|
||||
D3DXSaveTextureToFile(fname, D3DXIFF_PNG, entry.texture, NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Only used by Qt UI?
|
||||
bool TextureCacheDX9::DecodeTexture(u8* output, GPUgstate state)
|
||||
{
|
||||
OutputDebugStringA("TextureCache::DecodeTexture : FixMe\r\n");
|
||||
|
|
|
@ -106,13 +106,6 @@ private:
|
|||
int maxLevel;
|
||||
float lodBias;
|
||||
|
||||
// Cache the current filter settings so we can avoid setting it again.
|
||||
// (OpenGL madness where filter settings are attached to each texture).
|
||||
u8 magFilt;
|
||||
u8 minFilt;
|
||||
bool sClamp;
|
||||
bool tClamp;
|
||||
|
||||
bool Matches(u16 dim2, u8 format2, int maxLevel2);
|
||||
};
|
||||
|
||||
|
|
|
@ -154,8 +154,8 @@ static const DeclTypeInfo VComp[] = {
|
|||
{D3DDECLTYPE_UBYTE4N ,"D3DDECLTYPE_UBYTE4N "}, // DEC_U8_2,
|
||||
{D3DDECLTYPE_UBYTE4N ,"D3DDECLTYPE_UBYTE4N "}, // DEC_U8_3,
|
||||
{D3DDECLTYPE_UBYTE4N ,"D3DDECLTYPE_UBYTE4N "}, // DEC_U8_4,
|
||||
{D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4N "}, // DEC_U16_1,
|
||||
{D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4N "}, // DEC_U16_2,
|
||||
{D3DDECLTYPE_USHORT2N, "D3DDECLTYPE_USHORT2N " }, // DEC_U16_1,
|
||||
{D3DDECLTYPE_USHORT2N, "D3DDECLTYPE_USHORT2N " }, // DEC_U16_2,
|
||||
{D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4N "}, // DEC_U16_3,
|
||||
{D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4N "}, // DEC_U16_4,
|
||||
#ifdef _XBOX
|
||||
|
@ -164,7 +164,7 @@ static const DeclTypeInfo VComp[] = {
|
|||
#else
|
||||
// Not supported in regular DX9 so faking, will cause graphics bugs until worked around
|
||||
{D3DDECLTYPE_UBYTE4 ,"D3DDECLTYPE_BYTE4 "}, // DEC_U8A_2,
|
||||
{D3DDECLTYPE_USHORT4N ,"D3DDECLTYPE_USHORT4 "}, // DEC_U16A_2,
|
||||
{D3DDECLTYPE_USHORT2N, "D3DDECLTYPE_USHORT4 " }, // DEC_U16A_2,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -219,6 +219,7 @@ static void LogDecFmtForDraw(const DecVtxFormat &decFmt) {
|
|||
|
||||
//pD3Ddevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
|
||||
}
|
||||
|
||||
static void SetupDecFmtForDraw(LinkedShaderDX9 *program, const DecVtxFormat &decFmt, u32 pspFmt) {
|
||||
auto vertexDeclCached = vertexDeclMap.find(pspFmt);
|
||||
|
||||
|
@ -271,13 +272,15 @@ static void SetupDecFmtForDraw(LinkedShaderDX9 *program, const DecVtxFormat &dec
|
|||
memcpy(VertexElement, &end, sizeof(D3DVERTEXELEMENT9));
|
||||
|
||||
// Create declaration
|
||||
pD3Ddevice->CreateVertexDeclaration( VertexElements, &pHardwareVertexDecl );
|
||||
HRESULT hr = pD3Ddevice->CreateVertexDeclaration( VertexElements, &pHardwareVertexDecl );
|
||||
if (FAILED(hr)) {
|
||||
// Log
|
||||
LogDecFmtForDraw(decFmt);
|
||||
// DebugBreak();
|
||||
}
|
||||
|
||||
// Add it to map
|
||||
vertexDeclMap[pspFmt] = pHardwareVertexDecl;
|
||||
|
||||
// Log
|
||||
//LogDecFmtForDraw(decFmt);
|
||||
} else {
|
||||
// Set it from map
|
||||
pHardwareVertexDecl = vertexDeclCached->second;
|
||||
|
@ -1135,23 +1138,25 @@ rotateVBO:
|
|||
DEBUG_LOG(G3D, "Flush prim %i! %i verts in one go", prim, vertexCount);
|
||||
|
||||
SetupDecFmtForDraw(program, dec_->GetDecVtxFmt(), dec_->VertexType());
|
||||
pD3Ddevice->SetVertexDeclaration(pHardwareVertexDecl);
|
||||
|
||||
if (vb_ == NULL) {
|
||||
if (useElements) {
|
||||
pD3Ddevice->DrawIndexedPrimitiveUP(glprim[prim], 0, vertexCount, D3DPrimCount(glprim[prim], vertexCount), decIndex, D3DFMT_INDEX16, decoded, dec_->GetDecVtxFmt().stride);
|
||||
if (pHardwareVertexDecl) {
|
||||
pD3Ddevice->SetVertexDeclaration(pHardwareVertexDecl);
|
||||
if (vb_ == NULL) {
|
||||
if (useElements) {
|
||||
pD3Ddevice->DrawIndexedPrimitiveUP(glprim[prim], 0, vertexCount, D3DPrimCount(glprim[prim], vertexCount), decIndex, D3DFMT_INDEX16, decoded, dec_->GetDecVtxFmt().stride);
|
||||
} else {
|
||||
pD3Ddevice->DrawPrimitiveUP(glprim[prim], D3DPrimCount(glprim[prim], vertexCount), decoded, dec_->GetDecVtxFmt().stride);
|
||||
}
|
||||
} else {
|
||||
pD3Ddevice->DrawPrimitiveUP(glprim[prim], D3DPrimCount(glprim[prim], vertexCount), decoded, dec_->GetDecVtxFmt().stride);
|
||||
}
|
||||
} else {
|
||||
pD3Ddevice->SetStreamSource(0, vb_, 0, dec_->GetDecVtxFmt().stride);
|
||||
pD3Ddevice->SetStreamSource(0, vb_, 0, dec_->GetDecVtxFmt().stride);
|
||||
|
||||
if (useElements) {
|
||||
pD3Ddevice->SetIndices(ib_);
|
||||
if (useElements) {
|
||||
pD3Ddevice->SetIndices(ib_);
|
||||
|
||||
pD3Ddevice->DrawIndexedPrimitive(glprim[prim], 0, 0, 0, 0, D3DPrimCount(glprim[prim], vertexCount));
|
||||
} else {
|
||||
pD3Ddevice->DrawPrimitive(glprim[prim], 0, D3DPrimCount(glprim[prim], vertexCount));
|
||||
pD3Ddevice->DrawIndexedPrimitive(glprim[prim], 0, 0, 0, 0, D3DPrimCount(glprim[prim], vertexCount));
|
||||
} else {
|
||||
pD3Ddevice->DrawPrimitive(glprim[prim], 0, D3DPrimCount(glprim[prim], vertexCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -273,21 +273,20 @@ void VertexDecoderDX9::Step_Color4444() const
|
|||
{
|
||||
u8 *c = decoded_ + decFmt.c0off;
|
||||
u16 cdata = (u16)(*(u16_le*)(ptr_ + coloff));
|
||||
c[0] = Convert4To8((cdata >> (12)) & 0xF);
|
||||
c[1] = Convert4To8((cdata >> (0)) & 0xF);
|
||||
c[2] = Convert4To8((cdata >> (4)) & 0xF);
|
||||
c[3] = Convert4To8((cdata >> (8)) & 0xF);
|
||||
c[0] = Convert4To8((cdata >> (0)) & 0xF);
|
||||
c[1] = Convert4To8((cdata >> (4)) & 0xF);
|
||||
c[2] = Convert4To8((cdata >> (8)) & 0xF);
|
||||
c[3] = Convert4To8((cdata >> (12)) & 0xF);
|
||||
}
|
||||
|
||||
void VertexDecoderDX9::Step_Color8888() const
|
||||
{
|
||||
// Directx want ARGB
|
||||
u8 *c = (u8*)(decoded_ + decFmt.c0off);
|
||||
const u8 *cdata = (const u8*)(ptr_ + coloff);
|
||||
c[0] = cdata[3];
|
||||
c[1] = cdata[0];
|
||||
c[2] = cdata[1];
|
||||
c[3] = cdata[2];
|
||||
c[0] = cdata[2];
|
||||
c[1] = cdata[1];
|
||||
c[2] = cdata[0];
|
||||
c[3] = cdata[3];
|
||||
}
|
||||
|
||||
void VertexDecoderDX9::Step_Color565Morph() const
|
||||
|
@ -864,7 +863,7 @@ void VertexDecoderDX9::SetVertexType(u32 fmt) {
|
|||
// The normal formats match the gl formats perfectly, let's use 'em.
|
||||
switch (nrm) {
|
||||
//case GE_VTYPE_NRM_8BIT >> GE_VTYPE_NRM_SHIFT: decFmt.nrmfmt = DEC_S8_3; break;
|
||||
case GE_VTYPE_NRM_8BIT >> GE_VTYPE_NRM_SHIFT: decFmt.nrmfmt = DEC_FLOAT_3; break;
|
||||
case GE_VTYPE_NRM_8BIT >> GE_VTYPE_NRM_SHIFT: decFmt.nrmfmt = DEC_FLOAT_3; break;
|
||||
case GE_VTYPE_NRM_16BIT >> GE_VTYPE_NRM_SHIFT: decFmt.nrmfmt = DEC_S16_3; break;
|
||||
case GE_VTYPE_NRM_FLOAT >> GE_VTYPE_NRM_SHIFT: decFmt.nrmfmt = DEC_FLOAT_3; break;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ void DirectxState::Initialize() {
|
|||
|
||||
void DirectxState::Restore() {
|
||||
int count = 0;
|
||||
|
||||
blend.restore(); count++;
|
||||
blendEquation.restore(); count++;
|
||||
blendFunc.restore(); count++;
|
||||
|
@ -37,7 +38,8 @@ void DirectxState::Restore() {
|
|||
depthWrite.restore(); count++;
|
||||
|
||||
colorMask.restore(); count++;
|
||||
viewport.restore(); count++;
|
||||
|
||||
// viewport.restore(); count++;
|
||||
|
||||
stencilTest.restore(); count++;
|
||||
stencilOp.restore(); count++;
|
||||
|
@ -45,7 +47,14 @@ void DirectxState::Restore() {
|
|||
|
||||
dither.restore(); count++;
|
||||
|
||||
assert(count == state_count && "DirectxState::Restore is missing some states");
|
||||
texMinFilter.restore(); count++;
|
||||
texMagFilter.restore(); count++;
|
||||
texMipFilter.restore(); count++;
|
||||
texAddressU.restore(); count++;
|
||||
texAddressV.restore(); count++;
|
||||
|
||||
|
||||
//assert(count == state_count && "DirectxState::Restore is missing some states");
|
||||
}
|
||||
|
||||
void CheckGLExtensions() {
|
||||
|
|
|
@ -6,10 +6,7 @@
|
|||
|
||||
namespace DX9 {
|
||||
|
||||
// OpenGL state cache. Should convert all code to use this instead of directly calling glEnable etc,
|
||||
// as GL state changes can be expensive on some hardware.
|
||||
class DirectxState
|
||||
{
|
||||
class DirectxState {
|
||||
private:
|
||||
template<D3DRENDERSTATETYPE cap, bool init>
|
||||
class BoolState {
|
||||
|
@ -58,6 +55,24 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
template<D3DSAMPLERSTATETYPE state1, DWORD p1def>
|
||||
class DxSampler0State1 {
|
||||
D3DSAMPLERSTATETYPE _state1;
|
||||
DWORD p1;
|
||||
public:
|
||||
DxSampler0State1() : _state1(state1), p1(p1def) {
|
||||
DirectxState::state_count++;
|
||||
}
|
||||
|
||||
inline void set(DWORD newp1) {
|
||||
p1 = newp1;
|
||||
pD3Ddevice->SetSamplerState(0, _state1, p1);
|
||||
}
|
||||
void restore() {
|
||||
pD3Ddevice->SetSamplerState(0, _state1, p1);
|
||||
}
|
||||
};
|
||||
|
||||
template<D3DRENDERSTATETYPE state1, DWORD p1def, D3DRENDERSTATETYPE state2, DWORD p2def>
|
||||
class DxState2 {
|
||||
D3DRENDERSTATETYPE _state1;
|
||||
|
@ -104,12 +119,46 @@ private:
|
|||
pD3Ddevice->SetRenderState(_state3, p3);
|
||||
}
|
||||
void restore() {
|
||||
// pD3Ddevice->SetRenderState(_state1, p1);
|
||||
// pD3Ddevice->SetRenderState(_state2, p2);
|
||||
// pD3Ddevice->SetRenderState(_state3, p2);
|
||||
pD3Ddevice->SetRenderState(_state1, p1);
|
||||
pD3Ddevice->SetRenderState(_state2, p2);
|
||||
pD3Ddevice->SetRenderState(_state3, p3);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<D3DRENDERSTATETYPE state1, DWORD p1def, D3DRENDERSTATETYPE state2, DWORD p2def, D3DRENDERSTATETYPE state3, DWORD p3def, D3DRENDERSTATETYPE state4, DWORD p4def>
|
||||
class DxState4 {
|
||||
D3DRENDERSTATETYPE _state1;
|
||||
D3DRENDERSTATETYPE _state2;
|
||||
D3DRENDERSTATETYPE _state3;
|
||||
D3DRENDERSTATETYPE _state4;
|
||||
DWORD p1;
|
||||
DWORD p2;
|
||||
DWORD p3;
|
||||
DWORD p4;
|
||||
public:
|
||||
DxState4() : _state1(state1), _state2(state2), _state3(state3), _state4(state4),
|
||||
p1(p1def), p2(p2def), p3(p3def), p4(p4def) {
|
||||
// DirectxState::state_count++;
|
||||
}
|
||||
|
||||
inline void set(DWORD newp1, DWORD newp2, DWORD newp3, DWORD newp4) {
|
||||
p1 = newp1;
|
||||
p2 = newp2;
|
||||
p3 = newp3;
|
||||
p4 = newp4;
|
||||
pD3Ddevice->SetRenderState(_state1, p1);
|
||||
pD3Ddevice->SetRenderState(_state2, p2);
|
||||
pD3Ddevice->SetRenderState(_state3, p3);
|
||||
pD3Ddevice->SetRenderState(_state4, p4);
|
||||
}
|
||||
void restore() {
|
||||
pD3Ddevice->SetRenderState(_state1, p1);
|
||||
pD3Ddevice->SetRenderState(_state2, p2);
|
||||
pD3Ddevice->SetRenderState(_state3, p3);
|
||||
pD3Ddevice->SetRenderState(_state3, p4);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class SavedBlendFactor {
|
||||
DWORD c;
|
||||
|
@ -191,15 +240,6 @@ private:
|
|||
viewport.Y=y;
|
||||
viewport.Width=w;
|
||||
viewport.Height=h;
|
||||
/*
|
||||
if (f > n) {
|
||||
viewport.MinZ=n;
|
||||
viewport.MaxZ=f;
|
||||
} else {
|
||||
viewport.MinZ=f;
|
||||
viewport.MaxZ=n;
|
||||
}
|
||||
*/
|
||||
viewport.MinZ=n;
|
||||
viewport.MaxZ=f;
|
||||
|
||||
|
@ -232,12 +272,10 @@ private:
|
|||
cull = D3DCULL_NONE;
|
||||
} else {
|
||||
// add front face ...
|
||||
cull = cullmode==0?D3DCULL_CW:D3DCULL_CCW;
|
||||
cull = cullmode==0 ? D3DCULL_CW:D3DCULL_CCW;
|
||||
}
|
||||
|
||||
pD3Ddevice->SetRenderState(D3DRS_CULLMODE, cull);
|
||||
}
|
||||
|
||||
inline void restore() {
|
||||
pD3Ddevice->SetRenderState(D3DRS_CULLMODE, cull);
|
||||
}
|
||||
|
@ -253,8 +291,8 @@ public:
|
|||
|
||||
// When adding a state here, don't forget to add it to DirectxState::Restore() too
|
||||
BoolState<D3DRS_ALPHABLENDENABLE, false> blend;
|
||||
DxState2<D3DRS_SRCBLEND, D3DBLEND_SRCALPHA, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA> blendFunc;
|
||||
DxState1<D3DRS_BLENDOP, D3DBLENDOP_ADD> blendEquation;
|
||||
DxState4<D3DRS_SRCBLEND, D3DBLEND_SRCALPHA, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA, D3DRS_SRCBLENDALPHA, D3DBLEND_ONE, D3DRS_DESTBLENDALPHA, D3DBLEND_ZERO> blendFunc;
|
||||
DxState2<D3DRS_BLENDOP, D3DBLENDOP_ADD, D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD> blendEquation;
|
||||
SavedBlendFactor blendColor;
|
||||
|
||||
BoolState<D3DRS_SCISSORTESTENABLE, false> scissorTest;
|
||||
|
@ -278,6 +316,12 @@ public:
|
|||
DxState3<D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP> stencilOp;
|
||||
DxState3<D3DRS_STENCILFUNC, D3DCMP_ALWAYS, D3DRS_STENCILREF, 0, D3DRS_STENCILMASK, 0xFFFFFFFF> stencilFunc;
|
||||
|
||||
DxSampler0State1<D3DSAMP_MINFILTER, D3DTEXF_POINT> texMinFilter;
|
||||
DxSampler0State1<D3DSAMP_MAGFILTER, D3DTEXF_POINT> texMagFilter;
|
||||
DxSampler0State1<D3DSAMP_MIPFILTER, D3DTEXF_NONE> texMipFilter;
|
||||
DxSampler0State1<D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP> texAddressU;
|
||||
DxSampler0State1<D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP> texAddressV;
|
||||
|
||||
// Only works on Win32, all other platforms are "force-vsync"
|
||||
void SetVSyncInterval(int interval); // one of the above VSYNC, or a higher number for multi-frame waits (could be useful for 30hz games)
|
||||
};
|
||||
|
|
|
@ -2,12 +2,11 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "base/logging.h"
|
||||
#include "fbo.h"
|
||||
|
||||
namespace DX9 {
|
||||
|
||||
static LPDIRECT3DSURFACE9 currentRtt;
|
||||
static LPDIRECT3DSURFACE9 workingRtt;
|
||||
static LPDIRECT3DSURFACE9 deviceRTsurf;
|
||||
static LPDIRECT3DSURFACE9 deviceDSsurf;
|
||||
|
||||
|
@ -18,10 +17,6 @@ struct FBO {
|
|||
LPDIRECT3DSURFACE9 surf;
|
||||
LPDIRECT3DSURFACE9 depthstencil;
|
||||
LPDIRECT3DTEXTURE9 tex;
|
||||
uint32_t color_texture;
|
||||
uint32_t z_stencil_buffer; // Either this is set, or the two below.
|
||||
uint32_t z_buffer;
|
||||
uint32_t stencil_buffer;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
@ -31,8 +26,11 @@ struct FBO {
|
|||
void fbo_init() {
|
||||
pD3Ddevice->GetRenderTarget(0, &deviceRTsurf);
|
||||
pD3Ddevice->GetDepthStencilSurface(&deviceDSsurf);
|
||||
}
|
||||
|
||||
//pD3Ddevice->CreateRenderTarget(1280/FB_DIV, 720/FB_DIV, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &workingRtt, NULL);
|
||||
void fbo_shutdown() {
|
||||
deviceRTsurf->Release();
|
||||
deviceDSsurf->Release();
|
||||
}
|
||||
|
||||
FBO * current_fbo = NULL;
|
||||
|
@ -46,85 +44,49 @@ FBO *fbo_create(int width, int height, int num_color_textures, bool z_stencil, F
|
|||
fbo->height = height;
|
||||
fbo->colorDepth = colorDepth;
|
||||
|
||||
// only support 32bit surfaces
|
||||
//pD3Ddevice->CreateRenderTarget(fbo->width/4, fbo->height/4, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->surf, NULL);
|
||||
|
||||
/*
|
||||
// Create depth + stencil target | forced to 24-bit Z, 8-bit stencil
|
||||
pD3Ddevice->CreateDepthStencilSurface(fbo->width, fbo->height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL);
|
||||
*/
|
||||
// Only needed on xbox
|
||||
#ifdef _XBOX
|
||||
pD3Ddevice->CreateTexture(fbo->width/FB_DIV, fbo->height/FB_DIV, 1, 0, D3DFMT_A8R8G8B8, 0, &fbo->tex, NULL);
|
||||
if (workingRtt == NULL) {
|
||||
pD3Ddevice->CreateRenderTarget(fbo->width/FB_DIV, fbo->height/FB_DIV, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &workingRtt, NULL);
|
||||
HRESULT rtResult = pD3Ddevice->CreateTexture(fbo->width, fbo->height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &fbo->tex, NULL);
|
||||
if (FAILED(rtResult)) {
|
||||
ELOG("Failed to create render target");
|
||||
delete fbo;
|
||||
return NULL;
|
||||
}
|
||||
fbo->tex->GetSurfaceLevel(0, &fbo->surf);
|
||||
|
||||
HRESULT dsResult = pD3Ddevice->CreateDepthStencilSurface(fbo->width, fbo->height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL);
|
||||
if (FAILED(dsResult)) {
|
||||
ELOG("Failed to create depth buffer");
|
||||
fbo->surf->Release();
|
||||
fbo->tex->Release();
|
||||
delete fbo;
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
pD3Ddevice->CreateRenderTarget(fbo->width/4, fbo->height/4, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->surf, NULL);
|
||||
pD3Ddevice->CreateDepthStencilSurface(fbo->width, fbo->height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL);
|
||||
#endif
|
||||
|
||||
fbo->stencil_buffer = 8;
|
||||
fbo->z_buffer = 24;
|
||||
fbo->id = id++;
|
||||
return fbo;
|
||||
}
|
||||
|
||||
void fbo_destroy(FBO *fbo) {
|
||||
fbo->tex->Release();
|
||||
fbo->surf->Release();
|
||||
fbo->depthstencil->Release();
|
||||
delete fbo;
|
||||
}
|
||||
|
||||
void * fbo_get_rtt(FBO *fbo) {
|
||||
return fbo->tex;
|
||||
}
|
||||
|
||||
void fbo_unbind() {
|
||||
if (current_fbo != NULL) {
|
||||
|
||||
#ifdef _XBOX
|
||||
D3DVECTOR4 White = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
pD3Ddevice->Resolve( D3DRESOLVE_RENDERTARGET0|D3DRESOLVE_ALLFRAGMENTS|D3DRESOLVE_CLEARRENDERTARGET|D3DRESOLVE_CLEARDEPTHSTENCIL, NULL,
|
||||
current_fbo->tex, NULL, 0, 0, &White, 0.0f, 0, NULL );
|
||||
#else
|
||||
// TODO?
|
||||
#endif
|
||||
/*
|
||||
pD3Ddevice->Resolve( D3DRESOLVE_RENDERTARGET0|D3DRESOLVE_ALLFRAGMENTS, NULL,
|
||||
current_fbo->tex, NULL, 0, 0, 0, 0.0f, 0, NULL );
|
||||
*/
|
||||
//pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER, 0xFFFFFFFF, 0, 0);
|
||||
}
|
||||
|
||||
//pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER, 0xFFFFFFFF, 0, 0);
|
||||
current_fbo = NULL;
|
||||
|
||||
pD3Ddevice->SetRenderTarget(0, deviceRTsurf);
|
||||
//pD3Ddevice->SetDepthStencilSurface(deviceDSsurf);
|
||||
|
||||
currentRtt = deviceRTsurf;
|
||||
pD3Ddevice->SetDepthStencilSurface(deviceDSsurf);
|
||||
}
|
||||
|
||||
void fbo_resolve(FBO *fbo) {
|
||||
if (fbo && fbo->tex) {
|
||||
#ifdef _XBOX
|
||||
pD3Ddevice->Resolve( D3DRESOLVE_RENDERTARGET0|D3DRESOLVE_ALLFRAGMENTS, NULL, fbo->tex, NULL, 0, 0, NULL, 0.0f, 0, NULL );
|
||||
#else
|
||||
// TODO?
|
||||
#endif
|
||||
}
|
||||
#if 0
|
||||
// Hack save to disk ...
|
||||
char fname[256];
|
||||
static int f = 0;
|
||||
sprintf(fname, "game:\\rtt.%08x.%d.png", fbo->id, f++);
|
||||
D3DXSaveTextureToFile(fname, D3DXIFF_PNG, fbo->tex, NULL);
|
||||
//strcat(fname, "\n");
|
||||
OutputDebugString(fname);
|
||||
#endif
|
||||
}
|
||||
|
||||
void fbo_bind_as_render_target(FBO *fbo) {
|
||||
current_fbo = fbo;
|
||||
pD3Ddevice->SetRenderTarget(0, workingRtt);
|
||||
currentRtt = workingRtt;
|
||||
//pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER, 0xFFFFFFFF, 0, 0);
|
||||
//pD3Ddevice->SetDepthStencilSurface(fbo->depthstencil);
|
||||
pD3Ddevice->SetRenderTarget(0, fbo->surf);
|
||||
pD3Ddevice->SetDepthStencilSurface(fbo->depthstencil);
|
||||
}
|
||||
|
||||
void fbo_bind_for_read(FBO *fbo) {
|
||||
|
@ -132,37 +94,7 @@ void fbo_bind_for_read(FBO *fbo) {
|
|||
}
|
||||
|
||||
void fbo_bind_color_as_texture(FBO *fbo, int color) {
|
||||
|
||||
#if 0
|
||||
// Hack save to disk ...
|
||||
char fname[256];
|
||||
static int f = 0;
|
||||
sprintf(fname, "game:\\rtt.%08x.%d.png", fbo->id, f++);
|
||||
D3DXSaveTextureToFile(fname, D3DXIFF_PNG, fbo->tex, NULL);
|
||||
//strcat(fname, "\n");
|
||||
OutputDebugString(fname);
|
||||
#endif
|
||||
//pD3Ddevice->SetRenderTarget(0, workingRtt);
|
||||
//pD3Ddevice->Resolve( D3DRESOLVE_RENDERTARGET0|D3DRESOLVE_ALLFRAGMENTS, NULL, fbo->tex, NULL, 0, 0, NULL, 0.0f, 0, NULL );
|
||||
//pD3Ddevice->SetRenderTarget(0, currentRtt);
|
||||
|
||||
//OutputDebugStringA("fbo_bind_color_as_texture: Fix me\r\n");
|
||||
pD3Ddevice->SetTexture(0, fbo->tex);
|
||||
//pD3Ddevice->SetTexture(0, NULL);
|
||||
}
|
||||
|
||||
void fbo_destroy(FBO *fbo) {
|
||||
/*
|
||||
fbo->depthstencil->Release();
|
||||
*/
|
||||
//fbo->surf->Release();
|
||||
#ifdef _XBOX
|
||||
fbo->tex->Release();
|
||||
#else
|
||||
fbo->depthstencil->Release();
|
||||
fbo->surf->Release();
|
||||
#endif
|
||||
delete fbo;
|
||||
}
|
||||
|
||||
void fbo_get_dimensions(FBO *fbo, int *w, int *h) {
|
||||
|
@ -170,11 +102,4 @@ void fbo_get_dimensions(FBO *fbo, int *w, int *h) {
|
|||
*h = fbo->height;
|
||||
}
|
||||
|
||||
void SwapBuffer() {
|
||||
pD3Ddevice->Present(0, 0, 0, 0);
|
||||
|
||||
// :s
|
||||
//pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0 ,0), 0, 0);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
#include "global.h"
|
||||
#include "fbo.h"
|
||||
#include "thin3d/d3dx9_loader.h"
|
||||
|
||||
namespace DX9 {
|
||||
|
||||
|
@ -91,6 +92,19 @@ bool CompilePixelShader(const char * code, LPDIRECT3DPIXELSHADER9 * pShader, LPD
|
|||
&pShaderCode,
|
||||
&pErrorMsg,
|
||||
pShaderTable );
|
||||
#else
|
||||
// Compile pixel shader.
|
||||
hr = dyn_D3DXCompileShader(code,
|
||||
(UINT)strlen(code),
|
||||
NULL,
|
||||
NULL,
|
||||
"main",
|
||||
"ps_3_0",
|
||||
0,
|
||||
&pShaderCode,
|
||||
&pErrorMsg,
|
||||
pShaderTable);
|
||||
|
||||
#endif
|
||||
if( FAILED(hr) )
|
||||
{
|
||||
|
@ -128,6 +142,17 @@ bool CompileVertexShader(const char * code, LPDIRECT3DVERTEXSHADER9 * pShader, L
|
|||
&pShaderCode,
|
||||
&pErrorMsg,
|
||||
pShaderTable );
|
||||
#else
|
||||
hr = dyn_D3DXCompileShader(code,
|
||||
(UINT)strlen(code),
|
||||
NULL,
|
||||
NULL,
|
||||
"main",
|
||||
"vs_3_0",
|
||||
0,
|
||||
&pShaderCode,
|
||||
&pErrorMsg,
|
||||
pShaderTable);
|
||||
#endif
|
||||
if( FAILED(hr) )
|
||||
{
|
||||
|
@ -163,6 +188,19 @@ void CompileShaders() {
|
|||
&pShaderCode,
|
||||
&pErrorMsg,
|
||||
NULL );
|
||||
#else
|
||||
// Compile vertex shader.
|
||||
hr = dyn_D3DXCompileShader(vscode,
|
||||
(UINT)strlen(vscode),
|
||||
NULL,
|
||||
NULL,
|
||||
"main",
|
||||
"vs_2_0",
|
||||
0,
|
||||
&pShaderCode,
|
||||
&pErrorMsg,
|
||||
NULL);
|
||||
|
||||
#endif
|
||||
|
||||
if( FAILED(hr) )
|
||||
|
@ -189,6 +227,19 @@ void CompileShaders() {
|
|||
&pShaderCode,
|
||||
&pErrorMsg,
|
||||
NULL );
|
||||
#else
|
||||
// Compile pixel shader.
|
||||
hr = dyn_D3DXCompileShader(pscode,
|
||||
(UINT)strlen(pscode),
|
||||
NULL,
|
||||
NULL,
|
||||
"main",
|
||||
"ps_2_0",
|
||||
0,
|
||||
&pShaderCode,
|
||||
&pErrorMsg,
|
||||
NULL);
|
||||
|
||||
#endif
|
||||
|
||||
if( FAILED(hr) )
|
||||
|
|
|
@ -9,10 +9,11 @@
|
|||
#define D3DFMT(x) x
|
||||
#endif
|
||||
|
||||
namespace DX9 {
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <d3dx9.h>
|
||||
|
||||
struct ID3DXConstantTable;
|
||||
|
||||
namespace DX9 {
|
||||
|
||||
extern LPDIRECT3DDEVICE9 pD3Ddevice;
|
||||
|
||||
|
@ -22,8 +23,9 @@ extern LPDIRECT3DPIXELSHADER9 pFramebufferPixelShader; // Pixel Shader
|
|||
extern IDirect3DVertexDeclaration9* pFramebufferVertexDecl;
|
||||
extern IDirect3DVertexDeclaration9* pSoftVertexDecl;
|
||||
|
||||
bool CompilePixelShader(const char * code, LPDIRECT3DPIXELSHADER9 * pShader, LPD3DXCONSTANTTABLE * pShaderTable);
|
||||
bool CompileVertexShader(const char * code, LPDIRECT3DVERTEXSHADER9 * pShader, LPD3DXCONSTANTTABLE * pShaderTable);
|
||||
void CompileShaders();
|
||||
bool CompilePixelShader(const char * code, LPDIRECT3DPIXELSHADER9 * pShader, ID3DXConstantTable **pShaderTable);
|
||||
bool CompileVertexShader(const char * code, LPDIRECT3DVERTEXSHADER9 * pShader, ID3DXConstantTable **pShaderTable);
|
||||
void DirectxInit(HWND window);
|
||||
|
||||
#define D3DBLEND_UNK D3DSTENCILOP_FORCE_DWORD
|
||||
|
|
|
@ -94,6 +94,8 @@ SOURCES += $$P/native/audio/*.cpp \
|
|||
$$P/native/math/fast/*.c \
|
||||
$$P/native/net/*.cpp \
|
||||
$$P/native/profiler/profiler.cpp \
|
||||
$$P/native/thin3d/thin3d.cpp \
|
||||
$$P/native/thin3d/thin3d_gl.cpp \
|
||||
$$P/native/thread/*.cpp \
|
||||
$$P/native/ui/*.cpp \
|
||||
$$P/native/util/bits/*.cpp \
|
||||
|
|
|
@ -191,7 +191,7 @@ int MixBackgroundAudio(short *buffer, int size) {
|
|||
// last changed... (to prevent crazy amount of reads when skipping through a list)
|
||||
if (!at3Reader && bgGamePath.size() && (time_now_d() - gameLastChanged > 0.5)) {
|
||||
// Grab some audio from the current game and play it.
|
||||
GameInfo *gameInfo = g_gameInfoCache.GetInfo(bgGamePath, GAMEINFO_WANTSND);
|
||||
GameInfo *gameInfo = g_gameInfoCache.GetInfo(NULL, bgGamePath, GAMEINFO_WANTSND);
|
||||
if (!gameInfo)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include "Core/Config.h"
|
||||
#include "UI/ui_atlas.h"
|
||||
#include "UI/ControlMappingScreen.h"
|
||||
#include "UI/UIShader.h"
|
||||
#include "UI/GameSettingsScreen.h"
|
||||
|
||||
class ControlMapper : public UI::LinearLayout {
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "UI/OnScreenDisplay.h"
|
||||
#include "UI/ui_atlas.h"
|
||||
#include "UI/GamepadEmu.h"
|
||||
#include "UI/UIShader.h"
|
||||
|
||||
#include "UI/MainScreen.h"
|
||||
#include "UI/EmuScreen.h"
|
||||
|
|
|
@ -231,16 +231,20 @@ void SystemInfoScreen::CreateViews() {
|
|||
deviceSpecs->Add(new InfoItem("Threads", cores));
|
||||
#endif
|
||||
deviceSpecs->Add(new ItemHeader("GPU Information"));
|
||||
deviceSpecs->Add(new InfoItem("Vendor", (char *)glGetString(GL_VENDOR)));
|
||||
deviceSpecs->Add(new InfoItem("Model", (char *)glGetString(GL_RENDERER)));
|
||||
|
||||
Thin3DContext *thin3d = screenManager()->getThin3DContext();
|
||||
|
||||
deviceSpecs->Add(new InfoItem("3D API", thin3d->GetInfoString(T3DInfo::APINAME)));
|
||||
deviceSpecs->Add(new InfoItem("Vendor", thin3d->GetInfoString(T3DInfo::VENDOR)));
|
||||
deviceSpecs->Add(new InfoItem("Model", thin3d->GetInfoString(T3DInfo::RENDERER)));
|
||||
#ifdef _WIN32
|
||||
deviceSpecs->Add(new InfoItem("Driver Version", System_GetProperty(SYSPROP_GPUDRIVER_VERSION)));
|
||||
#endif
|
||||
deviceSpecs->Add(new ItemHeader("OpenGL Version Information"));
|
||||
std::string openGL = (char *)glGetString(GL_VERSION);
|
||||
openGL.resize(30);
|
||||
deviceSpecs->Add(new InfoItem("OpenGL", openGL));
|
||||
deviceSpecs->Add(new InfoItem("GLSL", (char *)glGetString(GL_SHADING_LANGUAGE_VERSION)));
|
||||
deviceSpecs->Add(new ItemHeader("Version Information"));
|
||||
std::string apiVersion = thin3d->GetInfoString(T3DInfo::APIVERSION);
|
||||
apiVersion.resize(30);
|
||||
deviceSpecs->Add(new InfoItem("API Version", apiVersion));
|
||||
deviceSpecs->Add(new InfoItem("Shading Language", thin3d->GetInfoString(T3DInfo::SHADELANGVERSION)));
|
||||
|
||||
#ifdef ANDROID
|
||||
char temp[256];
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
#include "UI/ui_atlas.h"
|
||||
#include "UI/OnScreenDisplay.h"
|
||||
#include "UI/GamepadEmu.h"
|
||||
#include "UI/UIShader.h"
|
||||
#include "UI/MainScreen.h"
|
||||
#include "UI/EmuScreen.h"
|
||||
#include "UI/DevScreens.h"
|
||||
|
@ -87,6 +86,9 @@ void EmuScreen::bootGame(const std::string &filename) {
|
|||
CoreParameter coreParam;
|
||||
coreParam.cpuCore = g_Config.bJit ? CPU_JIT : CPU_INTERPRETER;
|
||||
coreParam.gpuCore = g_Config.bSoftwareRendering ? GPU_SOFTWARE : GPU_GLES;
|
||||
if (g_Config.iGPUBackend == GPU_BACKEND_DIRECT3D9) {
|
||||
coreParam.gpuCore = GPU_DIRECTX9;
|
||||
}
|
||||
coreParam.enableSound = g_Config.bEnableSound;
|
||||
coreParam.fileToStart = filename;
|
||||
coreParam.mountIso = "";
|
||||
|
@ -136,11 +138,13 @@ void EmuScreen::bootComplete() {
|
|||
#endif
|
||||
memset(virtKeys, 0, sizeof(virtKeys));
|
||||
|
||||
const char *renderer = (const char*)glGetString(GL_RENDERER);
|
||||
if (strstr(renderer, "Chainfire3D") != 0) {
|
||||
osm.Show(s->T("Chainfire3DWarning", "WARNING: Chainfire3D detected, may cause problems"), 10.0f, 0xFF30a0FF, -1, true);
|
||||
} else if (strstr(renderer, "GLTools") != 0) {
|
||||
osm.Show(s->T("GLToolsWarning", "WARNING: GLTools detected, may cause problems"), 10.0f, 0xFF30a0FF, -1, true);
|
||||
if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) {
|
||||
const char *renderer = (const char*)glGetString(GL_RENDERER);
|
||||
if (strstr(renderer, "Chainfire3D") != 0) {
|
||||
osm.Show(s->T("Chainfire3DWarning", "WARNING: Chainfire3D detected, may cause problems"), 10.0f, 0xFF30a0FF, -1, true);
|
||||
} else if (strstr(renderer, "GLTools") != 0) {
|
||||
osm.Show(s->T("GLToolsWarning", "WARNING: GLTools detected, may cause problems"), 10.0f, 0xFF30a0FF, -1, true);
|
||||
}
|
||||
}
|
||||
|
||||
System_SendMessage("event", "startgame");
|
||||
|
@ -702,17 +706,24 @@ void EmuScreen::render() {
|
|||
return;
|
||||
|
||||
bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
|
||||
if (useBufferedRendering)
|
||||
if (useBufferedRendering && g_Config.iGPUBackend == GPU_BACKEND_OPENGL)
|
||||
fbo_unbind();
|
||||
|
||||
UIShader_Prepare();
|
||||
screenManager()->getUIContext()->RebindTexture();
|
||||
Thin3DContext *thin3d = screenManager()->getThin3DContext();
|
||||
|
||||
uiTexture->Bind(0);
|
||||
|
||||
glstate.viewport.set(0, 0, pixel_xres, pixel_yres);
|
||||
T3DViewport viewport;
|
||||
viewport.TopLeftX = 0;
|
||||
viewport.TopLeftY = 0;
|
||||
viewport.Width = pixel_xres;
|
||||
viewport.Height = pixel_yres;
|
||||
viewport.MaxDepth = 1.0;
|
||||
viewport.MinDepth = 0.0;
|
||||
thin3d->SetViewports(1, &viewport);
|
||||
glstate.viewport.restore();
|
||||
|
||||
ui_draw2d.Begin(UIShader_Get(), DBMODE_NORMAL);
|
||||
thin3d->SetBlendState(thin3d->GetBlendStatePreset(BS_STANDARD_ALPHA));
|
||||
ui_draw2d.Begin(thin3d->GetShaderSetPreset(SS_TEXTURE_COLOR_2D), DBMODE_NORMAL);
|
||||
|
||||
if (root_) {
|
||||
UI::LayoutViewHierarchy(*screenManager()->getUIContext(), root_);
|
||||
|
@ -757,7 +768,6 @@ void EmuScreen::render() {
|
|||
ui_draw2d.SetFontScale(1.0f, 1.0f);
|
||||
}
|
||||
|
||||
glsl_bind(UIShader_Get());
|
||||
ui_draw2d.End();
|
||||
ui_draw2d.Flush();
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "base/stringutil.h"
|
||||
#include "file/file_util.h"
|
||||
#include "file/zip_read.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
#include "thread/prioritizedworkqueue.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/StringUtils.h"
|
||||
|
@ -561,10 +562,8 @@ void GameInfoCache::FlushBGs() {
|
|||
}
|
||||
}
|
||||
|
||||
// This may run off-main-thread and we thus can't use the global
|
||||
// pspFileSystem (well, we could with synchronization but there might not
|
||||
// even be a game running).
|
||||
GameInfo *GameInfoCache::GetInfo(const std::string &gamePath, int wantFlags) {
|
||||
// Runs on the main thread.
|
||||
GameInfo *GameInfoCache::GetInfo(Thin3DContext *thin3d, const std::string &gamePath, int wantFlags) {
|
||||
GameInfo *info = 0;
|
||||
|
||||
auto iter = info_.find(gamePath);
|
||||
|
@ -574,16 +573,16 @@ GameInfo *GameInfoCache::GetInfo(const std::string &gamePath, int wantFlags) {
|
|||
// Need to start over. We'll just add a new work item.
|
||||
goto again;
|
||||
}
|
||||
if (info->iconDataLoaded) {
|
||||
SetupTexture(info, info->iconTextureData, info->iconTexture, info->timeIconWasLoaded);
|
||||
if (thin3d && info->iconDataLoaded) {
|
||||
SetupTexture(info, info->iconTextureData, thin3d, info->iconTexture, info->timeIconWasLoaded);
|
||||
info->iconDataLoaded = false;
|
||||
}
|
||||
if (info->pic0DataLoaded) {
|
||||
SetupTexture(info, info->pic0TextureData, info->pic0Texture, info->timePic0WasLoaded);
|
||||
if (thin3d && info->pic0DataLoaded) {
|
||||
SetupTexture(info, info->pic0TextureData, thin3d, info->pic0Texture, info->timePic0WasLoaded);
|
||||
info->pic0DataLoaded = false;
|
||||
}
|
||||
if (info->pic1DataLoaded) {
|
||||
SetupTexture(info, info->pic1TextureData, info->pic1Texture, info->timePic1WasLoaded);
|
||||
if (thin3d && info->pic1DataLoaded) {
|
||||
SetupTexture(info, info->pic1TextureData, thin3d, info->pic1Texture, info->timePic1WasLoaded);
|
||||
info->pic1DataLoaded = false;
|
||||
}
|
||||
iter->second->lastAccessedTime = time_now_d();
|
||||
|
@ -607,14 +606,14 @@ again:
|
|||
return info;
|
||||
}
|
||||
|
||||
void GameInfoCache::SetupTexture(GameInfo *info, std::string &textureData, Texture *&tex, double &loadTime) {
|
||||
void GameInfoCache::SetupTexture(GameInfo *info, std::string &textureData, Thin3DContext *thin3d, Thin3DTexture *&tex, double &loadTime) {
|
||||
if (textureData.size()) {
|
||||
if (!tex) {
|
||||
tex = new Texture();
|
||||
if (tex->LoadPNG((const u8 *)textureData.data(), textureData.size(), false)) {
|
||||
tex = thin3d->CreateTextureFromFileData(textureData.data(), textureData.size(), T3DFileType::PNG);
|
||||
if (tex) {
|
||||
loadTime = time_now_d();
|
||||
} else {
|
||||
delete tex;
|
||||
tex->Release();
|
||||
tex = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,10 +23,12 @@
|
|||
#include "base/mutex.h"
|
||||
#include "file/file_util.h"
|
||||
#include "thread/prioritizedworkqueue.h"
|
||||
#include "gfx/texture.h"
|
||||
#include "Core/ELF/ParamSFO.h"
|
||||
#include "Core/Loaders.h"
|
||||
|
||||
class Thin3DContext;
|
||||
class Thin3DTexture;
|
||||
|
||||
// A GameInfo holds information about a game, and also lets you do things that the VSH
|
||||
// does on the PSP, namely checking for and deleting savedata, and similar things.
|
||||
// Only cares about games that are installed on the current device.
|
||||
|
@ -128,11 +130,11 @@ public:
|
|||
|
||||
// Pre read the data, create a texture the next time (GL thread..)
|
||||
std::string iconTextureData;
|
||||
Texture *iconTexture;
|
||||
Thin3DTexture *iconTexture;
|
||||
std::string pic0TextureData;
|
||||
Texture *pic0Texture;
|
||||
Thin3DTexture *pic0Texture;
|
||||
std::string pic1TextureData;
|
||||
Texture *pic1Texture;
|
||||
Thin3DTexture *pic1Texture;
|
||||
|
||||
std::string sndFileData;
|
||||
|
||||
|
@ -170,7 +172,7 @@ public:
|
|||
// but filled in later asynchronously in the background. So keep calling this,
|
||||
// redrawing the UI often. Only set flags to GAMEINFO_WANTBG or WANTSND if you really want them
|
||||
// because they're big. bgTextures and sound may be discarded over time as well.
|
||||
GameInfo *GetInfo(const std::string &gamePath, int wantFlags);
|
||||
GameInfo *GetInfo(Thin3DContext *thin3d, const std::string &gamePath, int wantFlags);
|
||||
void Decimate(); // Deletes old info.
|
||||
void FlushBGs(); // Gets rid of all BG textures. Also gets rid of bg sounds.
|
||||
|
||||
|
@ -179,7 +181,7 @@ public:
|
|||
void Load();
|
||||
|
||||
private:
|
||||
void SetupTexture(GameInfo *info, std::string &textureData, Texture *&tex, double &loadTime);
|
||||
void SetupTexture(GameInfo *info, std::string &textureData, Thin3DContext *thin3d, Thin3DTexture *&tex, double &loadTime);
|
||||
|
||||
// Maps ISO path to info.
|
||||
std::map<std::string, GameInfo *> info_;
|
||||
|
|
|
@ -45,7 +45,7 @@ GameScreen::~GameScreen() {
|
|||
}
|
||||
|
||||
void GameScreen::CreateViews() {
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
|
||||
I18NCategory *d = GetI18NCategory("Dialog");
|
||||
I18NCategory *ga = GetI18NCategory("Game");
|
||||
|
@ -64,7 +64,7 @@ void GameScreen::CreateViews() {
|
|||
|
||||
leftColumn->Add(new Choice(d->T("Back"), "", false, new AnchorLayoutParams(150, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle(this, &GameScreen::OnSwitchBack);
|
||||
if (info) {
|
||||
texvGameIcon_ = leftColumn->Add(new TextureView(0, IS_DEFAULT, new AnchorLayoutParams(144 * 2, 80 * 2, 10, 10, NONE, NONE)));
|
||||
texvGameIcon_ = leftColumn->Add(new Thin3DTextureView(0, IS_DEFAULT, new AnchorLayoutParams(144 * 2, 80 * 2, 10, 10, NONE, NONE)));
|
||||
tvTitle_ = leftColumn->Add(new TextView(info->title, ALIGN_LEFT, false, new AnchorLayoutParams(10, 200, NONE, NONE)));
|
||||
// This one doesn't need to be updated.
|
||||
leftColumn->Add(new TextView(gamePath_, ALIGN_LEFT, true, new AnchorLayoutParams(10, 250, NONE, NONE)));
|
||||
|
@ -105,7 +105,10 @@ void GameScreen::update(InputState &input) {
|
|||
UIScreen::update(input);
|
||||
|
||||
I18NCategory *ga = GetI18NCategory("Game");
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
|
||||
Thin3DContext *thin3d = screenManager()->getThin3DContext();
|
||||
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(thin3d, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
|
||||
if (tvTitle_)
|
||||
tvTitle_->SetText(info->title + " (" + info->id + ")");
|
||||
|
@ -166,7 +169,7 @@ UI::EventReturn GameScreen::OnPlay(UI::EventParams &e) {
|
|||
}
|
||||
|
||||
UI::EventReturn GameScreen::OnGameSettings(UI::EventParams &e) {
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
if (info && info->paramSFOLoaded) {
|
||||
std::string discID = info->paramSFO.GetValueString("DISC_ID");
|
||||
screenManager()->push(new GameSettingsScreen(gamePath_, discID));
|
||||
|
@ -177,7 +180,7 @@ UI::EventReturn GameScreen::OnGameSettings(UI::EventParams &e) {
|
|||
UI::EventReturn GameScreen::OnDeleteSaveData(UI::EventParams &e) {
|
||||
I18NCategory *d = GetI18NCategory("Dialog");
|
||||
I18NCategory *ga = GetI18NCategory("Game");
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
if (info) {
|
||||
// Check that there's any savedata to delete
|
||||
std::vector<std::string> saveDirs = info->GetSaveDataDirectories();
|
||||
|
@ -193,7 +196,7 @@ UI::EventReturn GameScreen::OnDeleteSaveData(UI::EventParams &e) {
|
|||
}
|
||||
|
||||
void GameScreen::CallbackDeleteSaveData(bool yes) {
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, 0);
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, 0);
|
||||
if (yes) {
|
||||
info->DeleteAllSaveData();
|
||||
info->saveDataSize = 0;
|
||||
|
@ -204,7 +207,7 @@ void GameScreen::CallbackDeleteSaveData(bool yes) {
|
|||
UI::EventReturn GameScreen::OnDeleteGame(UI::EventParams &e) {
|
||||
I18NCategory *d = GetI18NCategory("Dialog");
|
||||
I18NCategory *ga = GetI18NCategory("Game");
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
if (info) {
|
||||
screenManager()->push(
|
||||
new PromptScreen(d->T("DeleteConfirmGame", "Do you really want to delete this game\nfrom your device? You can't undo this."), ga->T("ConfirmDelete"), d->T("Cancel"),
|
||||
|
@ -215,7 +218,7 @@ UI::EventReturn GameScreen::OnDeleteGame(UI::EventParams &e) {
|
|||
}
|
||||
|
||||
void GameScreen::CallbackDeleteGame(bool yes) {
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, 0);
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, 0);
|
||||
if (yes) {
|
||||
info->DeleteGame();
|
||||
g_gameInfoCache.Clear();
|
||||
|
@ -224,7 +227,7 @@ void GameScreen::CallbackDeleteGame(bool yes) {
|
|||
}
|
||||
|
||||
UI::EventReturn GameScreen::OnCreateShortcut(UI::EventParams &e) {
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, 0);
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, 0);
|
||||
if (info) {
|
||||
host->CreateDesktopShortcut(gamePath_, info->title);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ private:
|
|||
UI::EventReturn OnShowInFolder(UI::EventParams &e);
|
||||
|
||||
// As we load metadata in the background, we need to be able to update these after the fact.
|
||||
UI::TextureView *texvGameIcon_;
|
||||
UI::Thin3DTextureView *texvGameIcon_;
|
||||
UI::TextView *tvTitle_;
|
||||
UI::TextView *tvGameSize_;
|
||||
UI::TextView *tvSaveDataSize_;
|
||||
|
|
|
@ -63,7 +63,7 @@ bool GameSettingsScreen::UseVerticalLayout() const {
|
|||
}
|
||||
|
||||
void GameSettingsScreen::CreateViews() {
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
GameInfo *info = g_gameInfoCache.GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
|
||||
|
||||
cap60FPS_ = g_Config.iForceMaxEmulatedFPS == 60;
|
||||
|
||||
|
|
|
@ -174,8 +174,8 @@ private:
|
|||
};
|
||||
|
||||
void GameButton::Draw(UIContext &dc) {
|
||||
GameInfo *ginfo = g_gameInfoCache.GetInfo(gamePath_, 0);
|
||||
Texture *texture = 0;
|
||||
GameInfo *ginfo = g_gameInfoCache.GetInfo(dc.GetThin3DContext(), gamePath_, 0);
|
||||
Thin3DTexture *texture = 0;
|
||||
u32 color = 0, shadowColor = 0;
|
||||
|
||||
if (ginfo->iconTexture) {
|
||||
|
@ -249,7 +249,7 @@ void GameButton::Draw(UIContext &dc) {
|
|||
|
||||
if (texture) {
|
||||
dc.Draw()->Flush();
|
||||
texture->Bind(0);
|
||||
dc.GetThin3DContext()->SetTexture(0, texture);
|
||||
if (holdFrameCount_ > 60) {
|
||||
// Blink before launching by holding
|
||||
if (((holdFrameCount_ >> 3) & 1) == 0)
|
||||
|
@ -959,7 +959,7 @@ bool MainScreen::DrawBackgroundFor(UIContext &dc, const std::string &gamePath, f
|
|||
|
||||
GameInfo *ginfo = 0;
|
||||
if (!gamePath.empty()) {
|
||||
ginfo = g_gameInfoCache.GetInfo(gamePath, GAMEINFO_WANTBG);
|
||||
ginfo = g_gameInfoCache.GetInfo(dc.GetThin3DContext(), gamePath, GAMEINFO_WANTBG);
|
||||
// Loading texture data may bind a texture.
|
||||
dc.RebindTexture();
|
||||
|
||||
|
@ -972,9 +972,9 @@ bool MainScreen::DrawBackgroundFor(UIContext &dc, const std::string &gamePath, f
|
|||
}
|
||||
|
||||
if (ginfo->pic1Texture) {
|
||||
ginfo->pic1Texture->Bind(0);
|
||||
dc.GetThin3DContext()->SetTexture(0, ginfo->pic1Texture);
|
||||
} else if (ginfo->pic0Texture) {
|
||||
ginfo->pic0Texture->Bind(0);
|
||||
dc.GetThin3DContext()->SetTexture(0, ginfo->pic0Texture);
|
||||
}
|
||||
|
||||
uint32_t color = whiteAlpha(ease(progress)) & 0xFFc0c0c0;
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "base/colorutil.h"
|
||||
#include "base/timeutil.h"
|
||||
#include "gfx_es2/draw_buffer.h"
|
||||
#include "gfx_es2/gl_state.h"
|
||||
#include "file/vfs.h"
|
||||
#include "math/curves.h"
|
||||
#include "i18n/i18n.h"
|
||||
|
@ -85,11 +84,8 @@ void DrawBackground(UIContext &dc, float alpha = 1.0f) {
|
|||
last_xres = xres;
|
||||
last_yres = yres;
|
||||
}
|
||||
|
||||
glstate.depthWrite.set(GL_TRUE);
|
||||
glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glClearColor(0.1f, 0.2f, 0.43f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
dc.GetThin3DContext()->Clear(T3DClear::COLOR | T3DClear::DEPTH | T3DClear::STENCIL, 0xff224477, 0.0, 0);
|
||||
int img = I_BG;
|
||||
#ifdef GOLD
|
||||
img = I_BG_GOLD;
|
||||
|
@ -106,18 +102,18 @@ void DrawBackground(UIContext &dc, float alpha = 1.0f) {
|
|||
}
|
||||
|
||||
void DrawGameBackground(UIContext &dc, const std::string &gamePath) {
|
||||
GameInfo *ginfo = g_gameInfoCache.GetInfo(gamePath, GAMEINFO_WANTBG);
|
||||
GameInfo *ginfo = g_gameInfoCache.GetInfo(dc.GetThin3DContext(), gamePath, GAMEINFO_WANTBG);
|
||||
dc.Flush();
|
||||
|
||||
if (ginfo) {
|
||||
bool hasPic = false;
|
||||
double loadTime;
|
||||
if (ginfo->pic1Texture) {
|
||||
ginfo->pic1Texture->Bind(0);
|
||||
dc.GetThin3DContext()->SetTexture(0, ginfo->pic1Texture);
|
||||
loadTime = ginfo->timePic1WasLoaded;
|
||||
hasPic = true;
|
||||
} else if (ginfo->pic0Texture) {
|
||||
ginfo->pic0Texture->Bind(0);
|
||||
dc.GetThin3DContext()->SetTexture(0, ginfo->pic0Texture);
|
||||
loadTime = ginfo->timePic0WasLoaded;
|
||||
hasPic = true;
|
||||
}
|
||||
|
@ -396,7 +392,6 @@ bool LogoScreen::key(const KeyInput &key) {
|
|||
|
||||
void LogoScreen::render() {
|
||||
UIScreen::render();
|
||||
|
||||
UIContext &dc = *screenManager()->getUIContext();
|
||||
|
||||
const Bounds &bounds = dc.GetBounds();
|
||||
|
@ -435,6 +430,8 @@ void LogoScreen::render() {
|
|||
ui_draw2d.DrawTextShadow(UBUNTU24, boot_filename.c_str(), bounds.centerX(), bounds.centerY() + 180, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER);
|
||||
}
|
||||
|
||||
dc.DrawText(screenManager()->getThin3DContext()->GetInfoString(T3DInfo::APINAME), bounds.centerX(), bounds.y2() - 100, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER);
|
||||
|
||||
dc.End();
|
||||
dc.Flush();
|
||||
}
|
||||
|
|
107
UI/NativeApp.cpp
107
UI/NativeApp.cpp
|
@ -38,6 +38,7 @@
|
|||
#include "ext/jpge/jpge.h"
|
||||
#include "Windows/DSoundStream.h"
|
||||
#include "Windows/WndMainWindow.h"
|
||||
#include "Windows/D3D9Base.h"
|
||||
#endif
|
||||
|
||||
#include "base/display.h"
|
||||
|
@ -48,7 +49,7 @@
|
|||
#include "file/zip_read.h"
|
||||
#include "thread/thread.h"
|
||||
#include "net/http_client.h"
|
||||
#include "gfx_es2/gl_state.h"
|
||||
#include "gfx_es2/gl_state.h" // only for screenshot!
|
||||
#include "gfx_es2/draw_text.h"
|
||||
#include "gfx_es2/draw_buffer.h"
|
||||
#include "gfx/gl_lost_manager.h"
|
||||
|
@ -58,6 +59,7 @@
|
|||
#include "math/fast/fast_math.h"
|
||||
#include "math/math_util.h"
|
||||
#include "math/lin/matrix4x4.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
#include "ui/ui.h"
|
||||
#include "ui/screen.h"
|
||||
#include "ui/ui_context.h"
|
||||
|
@ -80,9 +82,10 @@
|
|||
#include "ui_atlas.h"
|
||||
#include "EmuScreen.h"
|
||||
#include "GameInfoCache.h"
|
||||
#include "UIShader.h"
|
||||
#include "HostTypes.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "GPU/Directx9/helper/dx_state.h"
|
||||
#endif
|
||||
#include "UI/OnScreenDisplay.h"
|
||||
#include "UI/MiscScreens.h"
|
||||
#include "UI/TiltEventProcessor.h"
|
||||
|
@ -112,7 +115,7 @@ static UI::Theme ui_theme;
|
|||
#include "android/android-ndk-profiler/prof.h"
|
||||
#endif
|
||||
|
||||
Texture *uiTexture;
|
||||
Thin3DTexture *uiTexture;
|
||||
|
||||
ScreenManager *screenManager;
|
||||
std::string config_filename;
|
||||
|
@ -132,6 +135,7 @@ struct PendingMessage {
|
|||
|
||||
static recursive_mutex pendingMutex;
|
||||
static std::vector<PendingMessage> pendingMessages;
|
||||
static Thin3DContext *thin3d;
|
||||
static UIContext *uiContext;
|
||||
|
||||
std::thread *graphicsLoadThread;
|
||||
|
@ -463,12 +467,23 @@ void NativeInit(int argc, const char *argv[],
|
|||
void NativeInitGraphics() {
|
||||
FPU_SetFastMode();
|
||||
|
||||
CheckGLExtensions();
|
||||
#ifndef _WIN32
|
||||
// Force backend to GL
|
||||
g_Config.iGPUBackend = GPU_BACKEND_OPENGL;
|
||||
#endif
|
||||
|
||||
if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) {
|
||||
thin3d = T3DCreateGLContext();
|
||||
CheckGLExtensions();
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
thin3d = D3D9_CreateThin3DContext();
|
||||
#endif
|
||||
}
|
||||
|
||||
ui_draw2d.SetAtlas(&ui_atlas);
|
||||
ui_draw2d_front.SetAtlas(&ui_atlas);
|
||||
|
||||
UIShader_Init();
|
||||
|
||||
// memset(&ui_theme, 0, sizeof(ui_theme));
|
||||
// New style theme
|
||||
#ifdef _WIN32
|
||||
|
@ -487,18 +502,6 @@ void NativeInitGraphics() {
|
|||
ui_theme.sliderKnob = I_CIRCLE;
|
||||
ui_theme.dropShadow4Grid = I_DROP_SHADOW;
|
||||
|
||||
/*
|
||||
ui_theme.buttonStyle.background = UI::Drawable(UI::DRAW_4GRID, I_BUTTON);
|
||||
ui_theme.buttonStyle.fgColor = 0xFFFFFFFF;
|
||||
ui_theme.buttonStyle.image = I_BUTTON;
|
||||
ui_theme.buttonFocusedStyle.background = UI::Drawable(UI::DRAW_4GRID, I_BUTTON, 0xFFe0e0e0);
|
||||
ui_theme.buttonFocusedStyle.fgColor = 0xFFFFFFFF;
|
||||
ui_theme.buttonDownStyle.background = UI::Drawable(UI::DRAW_4GRID, I_BUTTON_SELECTED, 0xFFFFFFFF);
|
||||
ui_theme.buttonDownStyle.fgColor = 0xFFFFFFFF;
|
||||
ui_theme.buttonDisabledStyle.background = UI::Drawable(UI::DRAW_4GRID, I_BUTTON, 0xFF404040);
|
||||
ui_theme.buttonDisabledStyle.fgColor = 0xFF707070;
|
||||
*/
|
||||
|
||||
ui_theme.itemStyle.background = UI::Drawable(0x55000000);
|
||||
ui_theme.itemStyle.fgColor = 0xFFFFFFFF;
|
||||
ui_theme.itemFocusedStyle.background = UI::Drawable(0xFFedc24c);
|
||||
|
@ -526,27 +529,29 @@ void NativeInitGraphics() {
|
|||
ui_theme.popupTitle.fgColor = 0xFF59BEE3;
|
||||
#endif
|
||||
|
||||
ui_draw2d.Init();
|
||||
ui_draw2d_front.Init();
|
||||
ui_draw2d.Init(thin3d);
|
||||
ui_draw2d_front.Init(thin3d);
|
||||
|
||||
uiTexture = new Texture();
|
||||
#ifdef USING_QT_UI
|
||||
if (!uiTexture->Load("ui_atlas_lowmem.zim")) {
|
||||
uiTexture = thin3d->CreateTextureFromFile("ui_atlas_lowmem.zim");
|
||||
if (!uiTexture) {
|
||||
#else
|
||||
if (!uiTexture->Load("ui_atlas.zim")) {
|
||||
uiTexture = thin3d->CreateTextureFromFile("ui_atlas.zim", T3DFileType::ZIM);
|
||||
if (!uiTexture) {
|
||||
#endif
|
||||
PanicAlert("Failed to load ui_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory.");
|
||||
ELOG("Failed to load ui_atlas.zim");
|
||||
}
|
||||
uiTexture->Bind(0);
|
||||
|
||||
uiContext = new UIContext();
|
||||
uiContext->theme = &ui_theme;
|
||||
uiContext->Init(UIShader_Get(), UIShader_GetPlain(), uiTexture, &ui_draw2d, &ui_draw2d_front);
|
||||
|
||||
uiContext->Init(thin3d, thin3d->GetShaderSetPreset(SS_TEXTURE_COLOR_2D), thin3d->GetShaderSetPreset(SS_COLOR_2D), uiTexture, &ui_draw2d, &ui_draw2d_front);
|
||||
if (uiContext->Text())
|
||||
uiContext->Text()->SetFont("Tahoma", 20, 0);
|
||||
|
||||
screenManager->setUIContext(uiContext);
|
||||
screenManager->setThin3DContext(thin3d);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
@ -567,8 +572,7 @@ void NativeShutdownGraphics() {
|
|||
|
||||
g_gameInfoCache.Clear();
|
||||
|
||||
delete uiTexture;
|
||||
uiTexture = NULL;
|
||||
uiTexture->Release();
|
||||
|
||||
delete uiContext;
|
||||
uiContext = NULL;
|
||||
|
@ -576,11 +580,17 @@ void NativeShutdownGraphics() {
|
|||
ui_draw2d.Shutdown();
|
||||
ui_draw2d_front.Shutdown();
|
||||
|
||||
UIShader_Shutdown();
|
||||
thin3d->Release();
|
||||
}
|
||||
|
||||
void TakeScreenshot() {
|
||||
if (g_Config.iGPUBackend != GPU_BACKEND_OPENGL) {
|
||||
// Not yet supported
|
||||
return;
|
||||
}
|
||||
|
||||
g_TakeScreenshot = false;
|
||||
|
||||
#if defined(_WIN32) || (defined(USING_QT_UI) && !defined(MOBILE_DEVICE))
|
||||
mkDir(g_Config.memCardDirectory + "/PSP/SCREENSHOT");
|
||||
|
||||
|
@ -671,25 +681,43 @@ void DrawDownloadsOverlay(UIContext &dc) {
|
|||
void NativeRender() {
|
||||
g_GameManager.Update();
|
||||
|
||||
glstate.depthWrite.set(GL_TRUE);
|
||||
glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
T3DViewport viewport;
|
||||
viewport.TopLeftX = 0;
|
||||
viewport.TopLeftY = 0;
|
||||
viewport.Width = pixel_xres;
|
||||
viewport.Height = pixel_yres;
|
||||
viewport.MaxDepth = 1.0;
|
||||
viewport.MinDepth = 0.0;
|
||||
thin3d->SetViewports(1, &viewport);
|
||||
|
||||
// Clearing the screen at the start of the frame is an optimization for tiled mobile GPUs, as it then doesn't need to keep it around between frames.
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) {
|
||||
glstate.depthWrite.set(GL_TRUE);
|
||||
glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glstate.Restore();
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
DX9::dxstate.depthWrite.set(true);
|
||||
DX9::dxstate.colorMask.set(true, true, true, true);
|
||||
DX9::dxstate.Restore();
|
||||
#endif
|
||||
}
|
||||
|
||||
glstate.viewport.set(0, 0, pixel_xres, pixel_yres);
|
||||
glstate.Restore();
|
||||
thin3d->Clear(T3DClear::COLOR | T3DClear::DEPTH | T3DClear::STENCIL, 0xFF000000, 0.0f, 0);
|
||||
thin3d->SetTargetSize(pixel_xres, pixel_yres);
|
||||
|
||||
float xres = dp_xres;
|
||||
float yres = dp_yres;
|
||||
|
||||
// Apply the UIContext bounds as a 2D transformation matrix.
|
||||
Matrix4x4 ortho;
|
||||
ortho.setOrtho(0.0f, xres, yres, 0.0f, -1.0f, 1.0f);
|
||||
if (g_Config.iGPUBackend == GPU_BACKEND_DIRECT3D9) {
|
||||
ortho.setOrthoD3D(0.0f, xres, yres, 0.0f, -1.0f, 1.0f);
|
||||
} else {
|
||||
ortho.setOrtho(0.0f, xres, yres, 0.0f, -1.0f, 1.0f);
|
||||
}
|
||||
|
||||
glsl_bind(UIShader_Get());
|
||||
glUniformMatrix4fv(UIShader_Get()->u_worldviewproj, 1, GL_FALSE, ortho.getReadPtr());
|
||||
ui_draw2d.SetDrawMatrix(ortho);
|
||||
ui_draw2d_front.SetDrawMatrix(ortho);
|
||||
|
||||
screenManager->render();
|
||||
if (screenManager->getUIContext()->Text()) {
|
||||
|
@ -885,7 +913,6 @@ void NativeResized() {
|
|||
#if defined(__APPLE__) && !defined(USING_QT_UI)
|
||||
static int dp_xres_old=dp_xres;
|
||||
if (dp_xres != dp_xres_old) {
|
||||
UIShader_Init();
|
||||
uiTexture->Load("ui_atlas.zim");
|
||||
dp_xres_old = dp_xres;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
<ClCompile Include="TouchControlLayoutScreen.cpp" />
|
||||
<ClCompile Include="TouchControlVisibilityScreen.cpp" />
|
||||
<ClCompile Include="InstallZipScreen.cpp" />
|
||||
<ClCompile Include="UIShader.cpp" />
|
||||
<ClCompile Include="ui_atlas.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -60,7 +59,6 @@
|
|||
<ClInclude Include="TouchControlLayoutScreen.h" />
|
||||
<ClInclude Include="TouchControlVisibilityScreen.h" />
|
||||
<ClInclude Include="InstallZipScreen.h" />
|
||||
<ClInclude Include="UIShader.h" />
|
||||
<ClInclude Include="ui_atlas.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
|
@ -192,4 +190,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -5,7 +5,6 @@
|
|||
<ClCompile Include="GamepadEmu.cpp" />
|
||||
<ClCompile Include="NativeApp.cpp" />
|
||||
<ClCompile Include="ui_atlas.cpp" />
|
||||
<ClCompile Include="UIShader.cpp" />
|
||||
<ClCompile Include="OnScreenDisplay.cpp" />
|
||||
<ClCompile Include="EmuScreen.cpp">
|
||||
<Filter>Screens</Filter>
|
||||
|
@ -53,7 +52,6 @@
|
|||
<ClInclude Include="GameInfoCache.h" />
|
||||
<ClInclude Include="GamepadEmu.h" />
|
||||
<ClInclude Include="ui_atlas.h" />
|
||||
<ClInclude Include="UIShader.h" />
|
||||
<ClInclude Include="OnScreenDisplay.h" />
|
||||
<ClInclude Include="EmuScreen.h">
|
||||
<Filter>Screens</Filter>
|
||||
|
|
113
UI/UIShader.cpp
113
UI/UIShader.cpp
|
@ -1,113 +0,0 @@
|
|||
// 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 "gfx_es2/glsl_program.h"
|
||||
#include "gfx_es2/gl_state.h"
|
||||
#include "UIShader.h"
|
||||
|
||||
static GLSLProgram *glslModulate;
|
||||
static GLSLProgram *glslPlain;
|
||||
|
||||
static const char modulate_fs[] =
|
||||
"#ifdef GL_ES\n"
|
||||
"precision lowp float;\n"
|
||||
"#endif\n"
|
||||
"uniform sampler2D sampler0;\n"
|
||||
"varying vec2 v_texcoord0;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = texture2D(sampler0, v_texcoord0) * v_color;\n"
|
||||
"}\n";
|
||||
|
||||
static const char modulate_vs[] =
|
||||
"attribute vec4 a_position;\n"
|
||||
"attribute vec4 a_color;\n"
|
||||
"attribute vec2 a_texcoord0;\n"
|
||||
"uniform mat4 u_worldviewproj;\n"
|
||||
"varying vec2 v_texcoord0;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"void main() {\n"
|
||||
" v_texcoord0 = a_texcoord0;\n"
|
||||
" v_color = a_color;\n"
|
||||
" gl_Position = u_worldviewproj * a_position;\n"
|
||||
"}\n";
|
||||
|
||||
static const char plain_fs[] =
|
||||
"#ifdef GL_ES\n"
|
||||
"precision lowp float;\n"
|
||||
"#endif\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = v_color;\n"
|
||||
"}\n";
|
||||
|
||||
static const char plain_vs[] =
|
||||
"attribute vec4 a_position;\n"
|
||||
"attribute vec4 a_color;\n"
|
||||
"uniform mat4 u_worldviewproj;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"void main() {\n"
|
||||
" v_color = a_color;\n"
|
||||
" gl_Position = u_worldviewproj * a_position;\n"
|
||||
"}\n";
|
||||
|
||||
void UIShader_Init() {
|
||||
// Compile UI shaders
|
||||
glslModulate = glsl_create_source(modulate_vs, modulate_fs);
|
||||
glslPlain = glsl_create_source(plain_vs, plain_fs);
|
||||
}
|
||||
|
||||
GLSLProgram *UIShader_Get()
|
||||
{
|
||||
return glslModulate;
|
||||
}
|
||||
|
||||
|
||||
GLSLProgram *UIShader_GetPlain()
|
||||
{
|
||||
return glslPlain;
|
||||
}
|
||||
|
||||
void UIShader_Shutdown()
|
||||
{
|
||||
glsl_destroy(glslModulate);
|
||||
glsl_destroy(glslPlain);
|
||||
}
|
||||
|
||||
void UIShader_Prepare()
|
||||
{
|
||||
// Draw 2D overlay stuff
|
||||
glstate.cullFace.disable();
|
||||
glstate.depthTest.disable();
|
||||
glstate.scissorTest.disable();
|
||||
glstate.stencilTest.disable();
|
||||
glstate.stencilMask.set(0xFF);
|
||||
#if !defined(USING_GLES2)
|
||||
glstate.colorLogicOp.disable();
|
||||
#endif
|
||||
glstate.dither.enable();
|
||||
|
||||
glstate.blend.enable();
|
||||
glstate.blendFuncSeparate.set(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glstate.blendEquationSeparate.set(GL_FUNC_ADD, GL_FUNC_ADD);
|
||||
|
||||
glstate.depthWrite.set(GL_TRUE);
|
||||
glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glstate.Restore();
|
||||
|
||||
uiTexture->Bind(0);
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
// 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 "gfx_es2/glsl_program.h"
|
||||
#include "gfx/texture.h"
|
||||
|
||||
void UIShader_Init();
|
||||
GLSLProgram *UIShader_Get();
|
||||
GLSLProgram *UIShader_GetPlain(); // Just color
|
||||
void UIShader_Shutdown();
|
||||
|
||||
void UIShader_Prepare();
|
||||
|
||||
// TODO: Remove
|
||||
extern Texture *uiTexture;
|
123
Windows/D3D9Base.cpp
Normal file
123
Windows/D3D9Base.cpp
Normal file
|
@ -0,0 +1,123 @@
|
|||
#include "Common/CommonWindows.h"
|
||||
#include <d3d9.h>
|
||||
|
||||
#include "GPU/Directx9/helper/global.h"
|
||||
#include "GPU/Directx9/helper/fbo.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "util/text/utf8.h"
|
||||
#include "i18n/i18n.h"
|
||||
|
||||
#include "Core/Config.h"
|
||||
#include "Windows/D3D9Base.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
#include "thin3d/d3dx9_loader.h"
|
||||
|
||||
static LPDIRECT3D9 d3d;
|
||||
static int adapterId;
|
||||
static LPDIRECT3DDEVICE9 device;
|
||||
static HDC hDC; // Private GDI Device Context
|
||||
static HGLRC hRC; // Permanent Rendering Context
|
||||
static HWND hWnd; // Holds Our Window Handle
|
||||
|
||||
static int xres, yres;
|
||||
|
||||
// TODO: Make config?
|
||||
static bool enableGLDebug = true;
|
||||
|
||||
void D3D9_SwapBuffers() {
|
||||
device->EndScene();
|
||||
device->Present(NULL, NULL, NULL, NULL);
|
||||
device->BeginScene();
|
||||
}
|
||||
|
||||
Thin3DContext *D3D9_CreateThin3DContext() {
|
||||
return T3DCreateDX9Context(d3d, adapterId, device);
|
||||
}
|
||||
|
||||
bool D3D9_Init(HWND hWnd, bool windowed, std::string *error_message) {
|
||||
d3d = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
if (!d3d) {
|
||||
ELOG("Failed to create D3D context");
|
||||
return false;
|
||||
}
|
||||
|
||||
RECT rc;
|
||||
GetClientRect(hWnd, &rc);
|
||||
int xres = rc.right - rc.left;
|
||||
int yres = rc.bottom - rc.top;
|
||||
|
||||
D3DCAPS9 d3dCaps;
|
||||
|
||||
D3DDISPLAYMODE d3ddm;
|
||||
if (FAILED(d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) {
|
||||
d3d->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
adapterId = D3DADAPTER_DEFAULT;
|
||||
if (FAILED(d3d->GetDeviceCaps(adapterId, D3DDEVTYPE_HAL, &d3dCaps))) {
|
||||
d3d->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
if (FAILED(hr = d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
d3ddm.Format,
|
||||
D3DUSAGE_DEPTHSTENCIL,
|
||||
D3DRTYPE_SURFACE,
|
||||
D3DFMT_D24S8))) {
|
||||
if (hr == D3DERR_NOTAVAILABLE) {
|
||||
d3d->Release();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD dwBehaviorFlags = D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE;
|
||||
if (d3dCaps.VertexProcessingCaps != 0)
|
||||
dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
|
||||
else
|
||||
dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
|
||||
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
memset(&pp, 0, sizeof(pp));
|
||||
pp.BackBufferWidth = xres;
|
||||
pp.BackBufferHeight = yres;
|
||||
pp.BackBufferFormat = d3ddm.Format;
|
||||
pp.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
pp.Windowed = windowed;
|
||||
pp.hDeviceWindow = hWnd;
|
||||
pp.EnableAutoDepthStencil = true;
|
||||
pp.AutoDepthStencilFormat = D3DFMT_D24S8;
|
||||
pp.PresentationInterval = (g_Config.bVSync) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
|
||||
hr = d3d->CreateDevice(adapterId, D3DDEVTYPE_HAL, hWnd, dwBehaviorFlags, &pp, &device);
|
||||
if (FAILED(hr)) {
|
||||
ELOG("Failed to create D3D device");
|
||||
d3d->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
device->BeginScene();
|
||||
DX9::pD3Ddevice = device;
|
||||
|
||||
LoadD3DX9Dynamic();
|
||||
|
||||
DX9::CompileShaders();
|
||||
DX9::fbo_init();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D9_Resize(HWND window) {
|
||||
|
||||
}
|
||||
|
||||
void D3D9_Shutdown() {
|
||||
device->EndScene();
|
||||
device->Release();
|
||||
d3d->Release();
|
||||
hWnd = NULL;
|
||||
}
|
13
Windows/D3D9Base.h
Normal file
13
Windows/D3D9Base.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
// Modelled on OpenD3DBase. Might make a cleaner interface later.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/CommonWindows.h"
|
||||
|
||||
class Thin3DContext;
|
||||
|
||||
bool D3D9_Init(HWND window, bool windowed, std::string *error_message);
|
||||
void D3D9_Shutdown();
|
||||
void D3D9_Resize(HWND window);
|
||||
void D3D9_SwapBuffers();
|
||||
Thin3DContext *D3D9_CreateThin3DContext();
|
|
@ -106,7 +106,7 @@ unsigned int WINAPI TheThread(void *)
|
|||
|
||||
std::string error_string;
|
||||
if (!host->InitGL(&error_string)) {
|
||||
Reporting::ReportMessage("OpenGL init error: %s", error_string.c_str());
|
||||
Reporting::ReportMessage("Graphics init error: %s", error_string.c_str());
|
||||
std::string full_error = StringFromFormat( "Failed initializing OpenGL. Try upgrading your graphics drivers.\n\nError message:\n\n%s", error_string.c_str());
|
||||
MessageBox(0, ConvertUTF8ToWString(full_error).c_str(), L"OpenGL Error", MB_OK | MB_ICONERROR);
|
||||
ERROR_LOG(BOOT, full_error.c_str());
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003.
|
||||
|
||||
#include "util/text/utf8.h"
|
||||
#include "Common/CommonWindows.h"
|
||||
#include "native/gfx_es2/gl_state.h"
|
||||
#include "native/gfx/gl_common.h"
|
||||
#include "util/text/utf8.h"
|
||||
#include "GL/gl.h"
|
||||
#include "GL/wglew.h"
|
||||
#include "util/text/utf8.h"
|
||||
|
@ -71,6 +67,7 @@ void DebugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity,
|
|||
FILE *outFile = (FILE*)userParam;
|
||||
char finalMessage[256];
|
||||
FormatDebugOutputARB(finalMessage, 256, source, type, id, severity, message);
|
||||
OutputDebugStringA(finalMessage);
|
||||
ERROR_LOG(G3D, "GL: %s", finalMessage);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/CommonWindows.h"
|
||||
|
|
|
@ -277,6 +277,7 @@
|
|||
</ForcedIncludeFiles>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ControlMapping.cpp" />
|
||||
<ClCompile Include="D3D9Base.cpp" />
|
||||
<ClCompile Include="Debugger\BreakpointWindow.cpp" />
|
||||
<ClCompile Include="Debugger\CtrlDisAsmView.cpp" />
|
||||
<ClCompile Include="Debugger\CtrlMemView.cpp" />
|
||||
|
@ -330,6 +331,7 @@
|
|||
<ClInclude Include="..\android\jni\TestRunner.h" />
|
||||
<ClInclude Include="..\ios\ViewController.h" />
|
||||
<ClInclude Include="ControlMapping.h" />
|
||||
<ClInclude Include="D3D9Base.h" />
|
||||
<ClInclude Include="Debugger\BreakpointWindow.h" />
|
||||
<ClInclude Include="Debugger\CtrlDisAsmView.h" />
|
||||
<ClInclude Include="Debugger\CtrlMemView.h" />
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
<ClCompile Include="DSoundStream.cpp">
|
||||
<Filter>Windows\System</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="D3D9Base.cpp">
|
||||
<Filter>Windows\System</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="OpenGLBase.cpp">
|
||||
<Filter>Windows\System</Filter>
|
||||
</ClCompile>
|
||||
|
@ -187,6 +190,9 @@
|
|||
<ClInclude Include="DSoundStream.h">
|
||||
<Filter>Windows\System</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3D9Base.h">
|
||||
<Filter>Windows\System</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="OpenGLBase.h">
|
||||
<Filter>Windows\System</Filter>
|
||||
</ClInclude>
|
||||
|
@ -326,4 +332,4 @@
|
|||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "WindowsHost.h"
|
||||
#include "WndMainWindow.h"
|
||||
#include "OpenGLBase.h"
|
||||
#include "D3D9Base.h"
|
||||
|
||||
#include "Windows/Debugger/DebuggerShared.h"
|
||||
#include "Windows/Debugger/Debugger_Disasm.h"
|
||||
|
@ -88,14 +89,26 @@ WindowsHost::WindowsHost(HWND mainWindow, HWND displayWindow)
|
|||
SetConsolePosition();
|
||||
}
|
||||
|
||||
bool WindowsHost::InitGL(std::string *error_message)
|
||||
{
|
||||
return GL_Init(displayWindow_, error_message);
|
||||
bool WindowsHost::InitGL(std::string *error_message) {
|
||||
switch (g_Config.iGPUBackend) {
|
||||
case GPU_BACKEND_OPENGL:
|
||||
return GL_Init(displayWindow_, error_message);
|
||||
case GPU_BACKEND_DIRECT3D9:
|
||||
return D3D9_Init(displayWindow_, true, error_message);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void WindowsHost::ShutdownGL()
|
||||
{
|
||||
GL_Shutdown();
|
||||
void WindowsHost::ShutdownGL() {
|
||||
switch (g_Config.iGPUBackend) {
|
||||
case GPU_BACKEND_OPENGL:
|
||||
GL_Shutdown();
|
||||
break;
|
||||
case GPU_BACKEND_DIRECT3D9:
|
||||
D3D9_Shutdown();
|
||||
break;
|
||||
}
|
||||
PostMessage(mainWindow_, WM_CLOSE, 0, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -286,7 +286,6 @@ LOCAL_SRC_FILES := \
|
|||
$(SRC)/UI/MainScreen.cpp \
|
||||
$(SRC)/UI/MiscScreens.cpp \
|
||||
$(SRC)/UI/Store.cpp \
|
||||
$(SRC)/UI/UIShader.cpp \
|
||||
$(SRC)/UI/GamepadEmu.cpp \
|
||||
$(SRC)/UI/GameInfoCache.cpp \
|
||||
$(SRC)/UI/GameScreen.cpp \
|
||||
|
|
|
@ -66,7 +66,8 @@ public:
|
|||
};
|
||||
|
||||
struct InputState;
|
||||
// Temporary hack around annoying linking error.
|
||||
// Temporary hacks around annoying linking errors.
|
||||
void D3D9_SwapBuffers() { }
|
||||
void GL_SwapBuffers() { }
|
||||
void NativeUpdate(InputState &input_state) { }
|
||||
void NativeRender() { }
|
||||
|
|
2
native
2
native
|
@ -1 +1 @@
|
|||
Subproject commit 2ba8e36b2bde65021c9a5c0f937a0e3892c2ad62
|
||||
Subproject commit 467599cf5655625aa7fe8c9c409624a131cdd6bd
|
Loading…
Add table
Reference in a new issue