THIS BREAKS THE D3D PLUGIN FOR THE NEAR TERM. Resurrect an old patch that moves D3D over to the common shader generator framework. Needs a lot more work.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2484 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2009-02-28 22:10:38 +00:00
parent ee44b2a639
commit ecbfec2a13
49 changed files with 1087 additions and 4262 deletions

View File

@ -22,3 +22,42 @@
//BP state
// STATE_TO_SAVE
BPMemory bpmem;
// The plugin must implement this.
void BPWritten(int addr, int changes, int newval);
// Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg()
void LoadBPReg(u32 value0)
{
//handle the mask register
int opcode = value0 >> 24;
int oldval = ((u32*)&bpmem)[opcode];
int newval = (oldval & ~bpmem.bpMask) | (value0 & bpmem.bpMask);
int changes = (oldval ^ newval) & 0xFFFFFF;
//reset the mask register
if (opcode != 0xFE)
bpmem.bpMask = 0xFFFFFF;
BPWritten(opcode, changes, newval);
}
// Called when loading a saved state.
// Needs more testing though.
void BPReload()
{
for (int i = 0; i < 254; i++)
{
switch (i) {
case 0x41:
case 0x45: //GXSetDrawDone
case 0x52:
case 0x65:
case 0x67: // set gp metric?
case BPMEM_PE_TOKEN_ID:
case BPMEM_PE_TOKEN_INT_ID:
// Cases in which we DON'T want to reload the BP
continue;
default:
BPWritten(i, 0xFFFFFF, ((u32*)&bpmem)[i]);
}
}
}

View File

@ -96,10 +96,13 @@ public:
virtual void SetupVertexPointers() const = 0;
virtual void EnableComponents(u32 components) {}
int GetVertexStride() const { return vertex_stride; }
static NativeVertexFormat *Create();
// TODO: move these in under private:
u32 m_components; // VB_HAS_X. Bitmask telling what vertex components are present.
u32 vertex_stride;
protected:
// Let subclasses construct.

View File

@ -261,7 +261,7 @@ static void Decode()
break;
case GX_CMD_INVL_VC:// Invalidate (vertex cache?)
DebugLog("Invalidate (vertex cache?)");
DEBUG_LOG("Invalidate (vertex cache?)");
break;
case GX_LOAD_BP_REG: //0x61

View File

@ -928,11 +928,11 @@ static bool WriteAlphaTest(char *&p)
break;
}
WRITE(p, "discard( ");
WRITE(p, "clip( ");
WriteAlphaCompare(p, 0, bpmem.alphaFunc.comp0);
// negated because testing the inverse condition
switch(bpmem.alphaFunc.logic) {
switch (bpmem.alphaFunc.logic) {
case 0: WRITE(p, " || "); break; // and
case 1: WRITE(p, " && "); break; // or
case 2: WRITE(p, " == "); break; // xor

View File

@ -5,12 +5,15 @@ Import('env')
files = [
'BPMemory.cpp',
'CPMemory.cpp',
'XFMemory.cpp',
'XFStructs.cpp',
'memcpy_amd.cpp',
'LookUpTables.cpp',
'OpcodeDecoding.cpp',
'TextureDecoder.cpp',
'XFMemory.cpp',
'XFBConvert.cpp',
'IndexGenerator.cpp',
'PixelShaderGen.cpp',
'PixelShaderManager.cpp',
'VertexShaderGen.cpp',

View File

@ -0,0 +1,62 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "VideoCommon.h"
#include <stdio.h>
#include <malloc.h>
static FILE* pfLog = NULL;
void __Log(const char *fmt, ...)
{
char* Msg = (char*)alloca(strlen(fmt)+512);
va_list ap;
va_start( ap, fmt );
vsnprintf( Msg, strlen(fmt)+512, fmt, ap );
va_end( ap );
g_VideoInitialize.pLog(Msg, FALSE);
if (pfLog == NULL)
pfLog = fopen(FULL_LOGS_DIR "oglgfx.txt", "w");
if (pfLog != NULL)
fwrite(Msg, strlen(Msg), 1, pfLog);
#ifdef _WIN32
// DWORD tmp;
// WriteConsole(hConsole, Msg, (DWORD)strlen(Msg), &tmp, 0);
#else
//printf("%s", Msg);
#endif
}
void __Log(int type, const char *fmt, ...)
{
char* Msg = (char*)alloca(strlen(fmt)+512);
va_list ap;
va_start( ap, fmt );
vsnprintf( Msg, strlen(fmt)+512, fmt, ap );
va_end( ap );
g_VideoInitialize.pLog(Msg, FALSE);
#ifdef _WIN32
// DWORD tmp;
// WriteConsole(hConsole, Msg, (DWORD)strlen(Msg), &tmp, 0);
#endif
}

View File

@ -16,11 +16,11 @@
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
#include "Globals.h"
#include "VideoCommon.h"
#include "XFMemory.h"
#include "VertexManager.h"
#include "CPMemory.h"
#include "NativeVertexWriter.h"
#include "VertexShaderManager.h"
#include "PixelShaderManager.h"
// LoadXFReg 0x10
void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
@ -41,7 +41,7 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
memcpy_gc(p1, &pData[i], transferSize*4);
i += transferSize;
}
else if (address<0x2000)
else if (address < 0x2000)
{
u32 data = pData[i];
switch (address)
@ -66,15 +66,13 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
break;
case 0x1006: //SetGPMetric
break;
case 0x1008: //__GXXfVtxSpecs, wrote 0004
xfregs.hostinfo = *(INVTXSPEC*)&data;
break;
case 0x1009: //GXSetNumChans (no)
if ((u32)xfregs.nNumChans != (data&3)) {
if ((u32)xfregs.nNumChans != (data & 3)) {
VertexManager::Flush();
xfregs.nNumChans = data&3;
xfregs.nNumChans = data & 3;
}
break;
case 0x100a: //GXSetChanAmbientcolor
@ -142,7 +140,7 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
case 0x1015:
case 0x1016:
case 0x1017:
DEBUG_LOG(VIDEO, "xf addr: %x=%x\n", address, data);
DEBUG_LOG("xf addr: %x=%x\n", address, data);
break;
case 0x1018:
//_assert_msg_(GX_XF, 0, "XF matrixindex0");
@ -156,7 +154,6 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
case 0x101a:
VertexManager::Flush();
VertexShaderManager::SetViewport((float*)&pData[i]);
PixelShaderManager::SetViewport((float*)&pData[i]);
i += 6;
break;
@ -195,7 +192,7 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
case 0x104d:
case 0x104e:
case 0x104f:
DEBUG_LOG(VIDEO, "xf addr: %x=%x\n", address, data);
DEBUG_LOG("xf addr: %x=%x\n", address, data);
break;
case 0x1050: xfregs.texcoords[0].postmtxinfo.hex = data; break;
case 0x1051: xfregs.texcoords[1].postmtxinfo.hex = data; break;
@ -207,7 +204,7 @@ void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
case 0x1057: xfregs.texcoords[7].postmtxinfo.hex = data; break;
default:
DEBUG_LOG(VIDEO, "xf addr: %x=%x\n", address, data);
DEBUG_LOG("xf addr: %x=%x\n", address, data);
break;
}
}
@ -228,9 +225,9 @@ void LoadIndexedXF(u32 val, int array)
//load stuff from array to address in xf mem
VertexManager::Flush();
VertexShaderManager::InvalidateXFRange(address, address + size);
//PRIM_LOG("xfmem iwrite: 0x%x-0x%x\n", address, address + size);
VertexShaderManager::InvalidateXFRange(address, address+size);
//PRIM_LOG("xfmem iwrite: 0x%x-0x%x\n", address, address+size);
for (int i = 0; i < size; i++)
xfmem[address + i] = Memory_Read_U32(arraybases[array] + arraystrides[array] * index + i * 4);
xfmem[address + i] = Memory_Read_U32(arraybases[array] + arraystrides[array]*index + i*4);
}

View File

@ -458,6 +458,14 @@
RelativePath=".\Src\XFMemory.h"
>
</File>
<File
RelativePath=".\Src\XFStructs.cpp"
>
</File>
<File
RelativePath=".\Src\XFStructs.h"
>
</File>
</Filter>
<Filter
Name="ShaderManagers"
@ -470,6 +478,14 @@
RelativePath=".\Src\PixelShaderManager.h"
>
</File>
<File
RelativePath=".\Src\VertexShaderManager.cpp"
>
</File>
<File
RelativePath=".\Src\VertexShaderManager.h"
>
</File>
</Filter>
<Filter
Name="Util"
@ -643,18 +659,14 @@
RelativePath=".\Src\VertexLoaderManager.h"
>
</File>
<File
RelativePath=".\Src\VertexShaderManager.cpp"
>
</File>
<File
RelativePath=".\Src\VertexShaderManager.h"
>
</File>
<File
RelativePath=".\Src\VideoCommon.h"
>
</File>
<File
RelativePath=".\Src\VideoLog.cpp"
>
</File>
</Files>
<Globals>
</Globals>

View File

@ -250,9 +250,9 @@ void Initialize(void *init)
}
#if defined(WIN32) && defined(_DEBUG)
int tmpflag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
tmpflag |= _CRTDBG_DELAY_FREE_MEM_DF;
_CrtSetDbgFlag(tmpflag);
//int tmpflag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
//tmpflag |= _CRTDBG_DELAY_FREE_MEM_DF;
//_CrtSetDbgFlag(tmpflag);
#endif
if (soundStream)

View File

@ -1185,98 +1185,18 @@
RelativePath=".\Src\BPStructs.h"
>
</File>
<File
RelativePath=".\Src\CPStructs.cpp"
>
</File>
<File
RelativePath=".\Src\CPStructs.h"
>
</File>
<File
RelativePath=".\Src\DecodedVArray.cpp"
>
</File>
<File
RelativePath=".\Src\DecodedVArray.h"
>
</File>
<File
RelativePath=".\Src\NativeVertexFormat.cpp"
>
</File>
<File
RelativePath=".\Src\TransformEngine.cpp"
>
</File>
<File
RelativePath=".\Src\TransformEngine.h"
>
</File>
<File
RelativePath=".\Src\VertexLoader.cpp"
>
</File>
<File
RelativePath=".\Src\VertexLoader.h"
>
</File>
<File
RelativePath=".\Src\VertexLoader_Color.h"
>
</File>
<File
RelativePath=".\Src\VertexLoader_MtxIndex.h"
>
</File>
<File
RelativePath=".\Src\VertexLoader_Normal.cpp"
>
</File>
<File
RelativePath=".\Src\VertexLoader_Normal.h"
>
</File>
<File
RelativePath=".\Src\VertexLoader_Position.h"
>
</File>
<File
RelativePath=".\Src\VertexLoader_TextCoord.h"
>
</File>
<File
RelativePath=".\Src\VertexLoaderManager.cpp"
>
</File>
<File
RelativePath=".\Src\VertexManager.cpp"
>
</File>
<File
RelativePath=".\Src\VertexManager.h"
>
</File>
<File
RelativePath=".\Src\XFStructs.cpp"
>
</File>
<File
RelativePath=".\Src\XFStructs.h"
RelativePath=".\Src\VertexShaderCache.cpp"
>
</File>
</Filter>
<Filter
Name="Render"
>
<File
RelativePath=".\Src\PixelShader.cpp"
>
</File>
<File
RelativePath=".\Src\PixelShader.h"
>
</File>
<File
RelativePath=".\Src\PixelShaderCache.cpp"
>
@ -1302,15 +1222,15 @@
>
</File>
<File
RelativePath=".\Src\VertexShader.cpp"
RelativePath=".\Src\VertexLoaderManager.cpp"
>
</File>
<File
RelativePath=".\Src\VertexShader.h"
RelativePath=".\Src\VertexManager.cpp"
>
</File>
<File
RelativePath=".\Src\VertexShaderCache.cpp"
RelativePath=".\Src\VertexManager.h"
>
</File>
<File

View File

@ -25,7 +25,8 @@
#include "TextureCache.h"
#include "TextureDecoder.h"
#include "VertexManager.h"
#include "PixelShader.h"
#include "PixelShaderGen.h"
#include "PixelShaderManager.h"
#include "Utils.h"
#include "main.h" //for the plugin interface
@ -34,8 +35,10 @@ bool textureChanged[8];
const bool renderFog = false;
using namespace D3D;
// State translation lookup tables
const D3DBLEND d3dSrcFactors[8] =
static const D3DBLEND d3dSrcFactors[8] =
{
D3DBLEND_ZERO,
D3DBLEND_ONE,
@ -47,7 +50,7 @@ const D3DBLEND d3dSrcFactors[8] =
D3DBLEND_INVDESTALPHA
};
const D3DBLEND d3dDestFactors[8] =
static const D3DBLEND d3dDestFactors[8] =
{
D3DBLEND_ZERO,
D3DBLEND_ONE,
@ -59,7 +62,7 @@ const D3DBLEND d3dDestFactors[8] =
D3DBLEND_INVDESTALPHA
};
const D3DCULL d3dCullModes[4] =
static const D3DCULL d3dCullModes[4] =
{
D3DCULL_NONE,
D3DCULL_CCW,
@ -67,7 +70,7 @@ const D3DCULL d3dCullModes[4] =
D3DCULL_CCW
};
const D3DCMPFUNC d3dCmpFuncs[8] =
static const D3DCMPFUNC d3dCmpFuncs[8] =
{
D3DCMP_NEVER,
D3DCMP_LESS,
@ -79,7 +82,7 @@ const D3DCMPFUNC d3dCmpFuncs[8] =
D3DCMP_ALWAYS
};
const D3DTEXTUREFILTERTYPE d3dMipFilters[4] =
static const D3DTEXTUREFILTERTYPE d3dMipFilters[4] =
{
D3DTEXF_NONE,
D3DTEXF_POINT,
@ -87,7 +90,7 @@ const D3DTEXTUREFILTERTYPE d3dMipFilters[4] =
D3DTEXF_LINEAR, //reserved
};
const D3DTEXTUREADDRESS d3dClamps[4] =
static const D3DTEXTUREADDRESS d3dClamps[4] =
{
D3DTADDRESS_CLAMP,
D3DTADDRESS_WRAP,
@ -101,7 +104,6 @@ void BPInit()
bpmem.bpMask = 0xFFFFFF;
}
using namespace D3D;
// __________________________________________________________________________________________________
// BPWritten
//
@ -116,12 +118,12 @@ void BPWritten(int addr, int changes, int newval)
((u32*)&bpmem)[addr] = newval;
// dev->SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]);
Renderer::SetRenderState( D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode] );
Renderer::SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]);
if (bpmem.genMode.cullmode == 3)
{
// dev->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
Renderer::SetRenderState( D3DRS_COLORWRITEENABLE, 0 );
Renderer::SetRenderState(D3DRS_COLORWRITEENABLE, 0);
}
else
{
@ -132,7 +134,7 @@ void BPWritten(int addr, int changes, int newval)
write |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE;
// dev->SetRenderState(D3DRS_COLORWRITEENABLE, write);
Renderer::SetRenderState( D3DRS_COLORWRITEENABLE, write );
Renderer::SetRenderState(D3DRS_COLORWRITEENABLE, write);
}
}
break;
@ -148,7 +150,7 @@ void BPWritten(int addr, int changes, int newval)
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
// PixelShaderMngr::SetIndMatrixChanged((addr-BPMEM_IND_MTX)/3);
PixelShaderManager::SetIndMatrixChanged((addr-BPMEM_IND_MTX)/3);
}
break;
case BPMEM_RAS1_SS0:
@ -156,7 +158,7 @@ void BPWritten(int addr, int changes, int newval)
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
// PixelShaderMngr::SetIndTexScaleChanged();
PixelShaderManager::SetIndTexScaleChanged();
}
break;
@ -171,9 +173,9 @@ void BPWritten(int addr, int changes, int newval)
// dev->SetRenderState(D3DRS_ZWRITEENABLE, bpmem.zmode.updateenable);
// dev->SetRenderState(D3DRS_ZFUNC,d3dCmpFuncs[bpmem.zmode.func]);
Renderer::SetRenderState( D3DRS_ZENABLE, TRUE );
Renderer::SetRenderState( D3DRS_ZWRITEENABLE, bpmem.zmode.updateenable );
Renderer::SetRenderState( D3DRS_ZFUNC, d3dCmpFuncs[bpmem.zmode.func] );
Renderer::SetRenderState(D3DRS_ZENABLE, TRUE);
Renderer::SetRenderState(D3DRS_ZWRITEENABLE, bpmem.zmode.updateenable);
Renderer::SetRenderState(D3DRS_ZFUNC, d3dCmpFuncs[bpmem.zmode.func]);
}
else
{
@ -181,50 +183,33 @@ void BPWritten(int addr, int changes, int newval)
// dev->SetRenderState(D3DRS_ZENABLE, FALSE);
// dev->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
Renderer::SetRenderState( D3DRS_ZENABLE, FALSE );
Renderer::SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
Renderer::SetRenderState(D3DRS_ZENABLE, FALSE);
Renderer::SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
}
//if (!bpmem.zmode.updateenable)
// Renderer::SetRenderMode(Renderer::RM_Normal);
}
break;
case BPMEM_ALPHACOMPARE:
if (changes)
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
float f[4] =
{
bpmem.alphaFunc.ref0/255.0f,
bpmem.alphaFunc.ref1/255.0f,
0,0
};
dev->SetPixelShaderConstantF(PS_CONST_ALPHAREF,f,1);
case BPMEM_ALPHACOMPARE:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d\n", bpmem.alphaFunc.ref0,
bpmem.alphaFunc.ref1, bpmem.alphaFunc.comp0, bpmem.alphaFunc.comp1, bpmem.alphaFunc.logic);
PixelShaderManager::SetAlpha(bpmem.alphaFunc);
}
break;
if (D3D::GetShaderVersion() == PSNONE)
{
// dev->SetRenderState(D3DRS_ALPHATESTENABLE, (Compare)bpmem.alphaFunc.comp0 != COMPARE_ALWAYS);
// dev->SetRenderState(D3DRS_ALPHAREF, bpmem.alphaFunc.ref0*4);
// dev->SetRenderState(D3DRS_ALPHAFUNC, d3dCmpFuncs[bpmem.alphaFunc.comp0]);
Renderer::SetRenderState( D3DRS_ALPHATESTENABLE, (Compare)bpmem.alphaFunc.comp0 != COMPARE_ALWAYS );
Renderer::SetRenderState( D3DRS_ALPHAREF, bpmem.alphaFunc.ref0 * 4 );
Renderer::SetRenderState( D3DRS_ALPHAFUNC, d3dCmpFuncs[bpmem.alphaFunc.comp0] );
}
// Normally, use texkill in pixel shader to emulate alpha test
}
break;
case BPMEM_CONSTANTALPHA:
if (changes)
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
float f[4] = {
bpmem.dstalpha.alpha/255.0f,0,0,0
};
dev->SetPixelShaderConstantF(PS_CONST_CONSTALPHA,f,1);
}
break;
case BPMEM_CONSTANTALPHA:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PRIM_LOG("constalpha: alp=%d, en=%d\n", bpmem.dstalpha.alpha, bpmem.dstalpha.enable);
PixelShaderManager::SetDestAlpha(bpmem.dstalpha);
}
break;
case BPMEM_LINEPTWIDTH:
{
@ -251,7 +236,7 @@ void BPWritten(int addr, int changes, int newval)
if (changes & 1)
{
// dev->SetRenderState(D3DRS_ALPHABLENDENABLE,bpmem.blendmode.blendenable);
Renderer::SetRenderState( D3DRS_ALPHABLENDENABLE, bpmem.blendmode.blendenable );
Renderer::SetRenderState(D3DRS_ALPHABLENDENABLE, bpmem.blendmode.blendenable);
}
if (changes & 2) {} // Logic op blending. D3D can't do this but can fake some modes.
if (changes & 4) {
@ -264,18 +249,18 @@ void BPWritten(int addr, int changes, int newval)
if (changes & 0x700)
{
// dev->SetRenderState(D3DRS_SRCBLEND, src);
Renderer::SetRenderState( D3DRS_SRCBLEND, src );
Renderer::SetRenderState(D3DRS_SRCBLEND, src);
}
if (changes & 0xE0) {
if (!bpmem.blendmode.subtract)
{
// dev->SetRenderState(D3DRS_DESTBLEND, dst);
Renderer::SetRenderState( D3DRS_DESTBLEND, dst );
Renderer::SetRenderState(D3DRS_DESTBLEND, dst);
}
else
{
// dev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
Renderer::SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
Renderer::SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
}
}
if (changes & 0x800) {
@ -283,20 +268,20 @@ void BPWritten(int addr, int changes, int newval)
{
// dev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
// dev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
Renderer::SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
Renderer::SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
Renderer::SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
Renderer::SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
}
else
{
// dev->SetRenderState(D3DRS_SRCBLEND, src);
// dev->SetRenderState(D3DRS_DESTBLEND, dst);
Renderer::SetRenderState( D3DRS_SRCBLEND, src );
Renderer::SetRenderState( D3DRS_DESTBLEND, dst );
Renderer::SetRenderState(D3DRS_SRCBLEND, src);
Renderer::SetRenderState(D3DRS_DESTBLEND, dst);
}
// dev->SetRenderState(D3DRS_BLENDOP,bpmem.blendmode.subtract?D3DBLENDOP_SUBTRACT:D3DBLENDOP_ADD);
Renderer::SetRenderState( D3DRS_BLENDOP, bpmem.blendmode.subtract ? D3DBLENDOP_SUBTRACT : D3DBLENDOP_ADD );
Renderer::SetRenderState(D3DRS_BLENDOP, bpmem.blendmode.subtract ? D3DBLENDOP_SUBTRACT : D3DBLENDOP_ADD);
}
//if (bpmem.blendmode.logicopenable) // && bpmem.blendmode.logicmode == 4)
// MessageBox(0,"LOGIC",0,0);
@ -311,13 +296,13 @@ void BPWritten(int addr, int changes, int newval)
write |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE;
// dev->SetRenderState(D3DRS_COLORWRITEENABLE, write);
Renderer::SetRenderState( D3DRS_COLORWRITEENABLE, write );
Renderer::SetRenderState(D3DRS_COLORWRITEENABLE, write);
}
}
break;
case BPMEM_FOGRANGE:
if(changes) {
if (changes) {
// TODO(XK): Fog range format
//Renderer::SetRenderState(D3DRS_FOGSTART, ...
//Renderer::SetRenderState(D3DRS_FOGEND, ...
@ -343,12 +328,12 @@ void BPWritten(int addr, int changes, int newval)
case BPMEM_FOGPARAM3:
//fog settings
if(changes) {
if (changes) {
static bool bFog = false;
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
if(!renderFog)
if (!renderFog)
break;
/// u32 fogCTemp = bpmem.fog.c_proj_fsel.cShifted12 << 12;
@ -359,7 +344,7 @@ void BPWritten(int addr, int changes, int newval)
switch(bpmem.fog.c_proj_fsel.fsel)
{
case 0: // Off
if(bFog) {
if (bFog) {
Renderer::SetRenderState(D3DRS_FOGENABLE, false);
bFog = false;
}
@ -383,7 +368,7 @@ void BPWritten(int addr, int changes, int newval)
break;
}
if(bpmem.fog.c_proj_fsel.fsel > 0 && !bFog) {
if (bpmem.fog.c_proj_fsel.fsel > 0 && !bFog) {
Renderer::SetRenderState(D3DRS_FOGENABLE, true);
bFog = true;
}
@ -392,11 +377,11 @@ void BPWritten(int addr, int changes, int newval)
break;
case BPMEM_FOGCOLOR:
if(changes) {
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
if(!renderFog)
if (!renderFog)
break;
// dev->SetRenderState(D3DRS_FOGCOLOR,bpmem.fog.color);
@ -414,35 +399,10 @@ void BPWritten(int addr, int changes, int newval)
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
Renderer::SetScissorRect();
}
break;
case BPMEM_SCISSORTL:
case BPMEM_SCISSORBR:
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
int xoff = bpmem.scissorOffset.x*2-342;
int yoff = bpmem.scissorOffset.y*2-342;
RECT rc;
rc.left=bpmem.scissorTL.x + xoff - 342 -1;
if (rc.left<0) rc.left=0;
rc.top=bpmem.scissorTL.y + yoff - 342 -1;
if (rc.top<0) rc.top=0;
rc.right=bpmem.scissorBR.x + xoff - 342 +2;
if (rc.right>640) rc.right=640;
rc.bottom=bpmem.scissorBR.y + yoff - 342 +2;
if (rc.bottom>480) rc.bottom=480;
char temp[256];
sprintf(temp,"ScissorRect: %i %i %i %i",rc.left,rc.top,rc.right,rc.bottom);
g_VideoInitialize.pLog(temp, FALSE);
// dev->SetRenderState(D3DRS_SCISSORTESTENABLE,TRUE);
Renderer::SetRenderState( D3DRS_SCISSORTESTENABLE, TRUE );
Renderer::SetScissorBox(rc);
}
break;
case BPMEM_ZTEX1:
if (changes) {
VertexManager::Flush();
@ -458,11 +418,146 @@ void BPWritten(int addr, int changes, int newval)
#ifdef _DEBUG
const char* pzop[] = {"DISABLE", "ADD", "REPLACE", "?"};
const char* pztype[] = {"Z8", "Z16", "Z24", "?"};
DebugLog("ztex op=%s, type=%s\n", pzop[bpmem.ztex2.op], pztype[bpmem.ztex2.type]);
DEBUG_LOG("ztex op=%s, type=%s\n", pzop[bpmem.ztex2.op], pztype[bpmem.ztex2.type]);
#endif
}
break;
case 0x45: //GXSetDrawDone
VertexManager::Flush();
switch (newval & 0xFF)
{
case 0x02:
g_VideoInitialize.pSetPEFinish(); // may generate interrupt
DEBUG_LOG("GXSetDrawDone SetPEFinish (value: 0x%02X)", (newval & 0xFFFF));
break;
default:
DEBUG_LOG("GXSetDrawDone ??? (value 0x%02X)", (newval & 0xFFFF));
break;
}
break;
case BPMEM_PE_TOKEN_ID:
g_VideoInitialize.pSetPEToken(static_cast<u16>(newval & 0xFFFF), FALSE);
DEBUG_LOG("SetPEToken 0x%04x", (newval & 0xFFFF));
break;
case BPMEM_PE_TOKEN_INT_ID:
g_VideoInitialize.pSetPEToken(static_cast<u16>(newval & 0xFFFF), TRUE);
DEBUG_LOG("SetPEToken + INT 0x%04x", (newval & 0xFFFF));
break;
case 0x67: // set gp metric?
break;
case BPMEM_TRIGGER_EFB_COPY:
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
RECT rc = {
(LONG)(bpmem.copyTexSrcXY.x*Renderer::GetXScale()),
(LONG)(bpmem.copyTexSrcXY.y*Renderer::GetYScale()),
(LONG)((bpmem.copyTexSrcXY.x+bpmem.copyTexSrcWH.x)*Renderer::GetXScale()),
(LONG)((bpmem.copyTexSrcXY.y+bpmem.copyTexSrcWH.y)*Renderer::GetYScale())
};
UPE_Copy PE_copy;
PE_copy.Hex = bpmem.triggerEFBCopy;
// clamp0
// clamp1
// target_pixel_format
// gamma
// scale_something
// clear
// frame_to_field
// copy_to_xfb
// ???: start Mem to/from EFB transfer
/* bool bMip = false; // ignored
if (bpmem.triggerEFBCopy & EFBCOPY_GENERATEMIPS)
bMip = true;*/
if (PE_copy.copy_to_xfb == 0) // bpmem.triggerEFBCopy & EFBCOPY_EFBTOTEXTURE)
{
// EFB to texture
// for some reason it sets bpmem.zcontrol.pixel_format to PIXELFMT_Z24 every time a zbuffer format is given as a dest to GXSetTexCopyDst
TextureCache::CopyEFBToRenderTarget(bpmem.copyTexDest<<5, &rc);
}
else
{
// EFB to XFB
// MessageBox(0, "WASDF", 0, 0);
Renderer::SwapBuffers();
PRIM_LOG("Renderer::SwapBuffers()");
g_VideoInitialize.pCopiedToXFB();
}
// clearing
if (PE_copy.clear) // bpmem.triggerEFBCopy & EFBCOPY_CLEAR)
{
// it seems that the GC is able to alpha blend on color-fill
// we cant do that so if alpha is != 255 we skip it
// clear color
u32 clearColor = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
if (bpmem.blendmode.colorupdate)
{
D3DRECT drc;
drc.x1 = rc.left;
drc.x2 = rc.right;
drc.y1 = rc.top;
drc.y2 = rc.bottom;
//D3D::dev->Clear(1, &drc, D3DCLEAR_STENCIL|D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,clearColor,1.0f,0);
//if ((clearColor>>24) == 255)
D3D::dev->ColorFill(D3D::GetBackBufferSurface(), &rc, clearColor);
}
else
{
// TODO:
// bpmem.blendmode.alphaupdate
// bpmem.blendmode.colorupdate
// i dunno how to implement a clear on alpha only or color only
}
// clear z-buffer
if (bpmem.zmode.updateenable)
{
float clearZ = (float)bpmem.clearZValue / float(0xFFFFFF);
if (clearZ > 1.0f) clearZ = 1.0f;
if (clearZ < 0.0f) clearZ = 0.0f;
D3D::dev->Clear(0, 0, D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0, clearZ, 0);
}
}
}
break;
case BPMEM_LOADTLUT: //GXLoadTlut
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
u32 tlutTMemAddr = (newval & 0x3FF) << 9;
u32 tlutXferCount = (newval & 0x1FFC00) >> 5;
u8 *ptr = 0;
// TODO - figure out a cleaner way.
if (g_VideoInitialize.bWii)
ptr = g_VideoInitialize.pGetMemoryPointer(bpmem.tlutXferSrc << 5);
else
ptr = g_VideoInitialize.pGetMemoryPointer((bpmem.tlutXferSrc & 0xFFFFF) << 5);
if (ptr)
memcpy_gc(texMem + tlutTMemAddr, ptr, tlutXferCount);
else
PanicAlert("Invalid palette pointer %08x %08x %08x", bpmem.tlutXferSrc, bpmem.tlutXferSrc << 5, (bpmem.tlutXferSrc & 0xFFFFF)<< 5);
// TODO(ector) : kill all textures that use this palette
// Not sure if it's a good idea, though. For now, we hash texture palettes
}
break;
case 0xf6: // ksel0
case 0xf7: // ksel1
case 0xf8: // ksel2
@ -475,12 +570,12 @@ void BPWritten(int addr, int changes, int newval)
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
// PixelShaderMngr::SetTevKSelChanged(addr-0xf6);
PixelShaderManager::SetTevKSelChanged(addr-0xf6);
}
break;
default:
switch(addr & 0xF8) //texture sampler filter
switch (addr & 0xF8) //texture sampler filter
{
case 0x80: // TEX MODE 0
case 0xA0:
@ -526,282 +621,112 @@ void BPWritten(int addr, int changes, int newval)
//g_VideoInitialize.pLog(temp);
}
break;
case 0x84://TEX MODE 1
case 0xA4:
break;
case 0x88://TEX IMAGE 0
case 0xA8:
if (changes)
{
textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
VertexManager::Flush();
}
break;
case 0x8C://TEX IMAGE 1
case 0xAC:
if (changes)
{
textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
VertexManager::Flush();
}
break;
case 0x90://TEX IMAGE 2
case 0xB0:
if (changes)
{
textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
VertexManager::Flush();
}
break;
case 0x94://TEX IMAGE 3
case 0xB4:
if (changes)
{
textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
VertexManager::Flush();
}
break;
case 0x98://TEX TLUT
case 0xB8:
if (changes)
{
textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
VertexManager::Flush();
}
break;
case 0x9C://TEX UNKNOWN
case 0xBC:
break;
case 0x84://TEX MODE 1
case 0xA4:
break;
case 0x88://TEX IMAGE 0
case 0xA8:
if (changes)
{
//textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
case 0x8C://TEX IMAGE 1
case 0xAC:
if (changes)
{
//textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
case 0x90://TEX IMAGE 2
case 0xB0:
if (changes)
{
//textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
case 0x94://TEX IMAGE 3
case 0xB4:
if (changes)
{
//textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
case 0x98://TEX TLUT
case 0xB8:
if (changes)
{
//textureChanged[((addr&0xE0)==0xA0)*4+(addr&3)] = true;
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
break;
case 0x9C://TEX UNKNOWN
case 0xBC:
//ERROR_LOG("texunknown%x = %x\n", addr, newval);
((u32*)&bpmem)[addr] = newval;
break;
case 0xE0:
case 0xE4:
((u32*)&bpmem)[addr] = newval;
if (addr&1) { // don't compare with changes!
VertexManager::Flush();
int num = (addr >> 1) & 0x3;
PixelShaderManager::SetColorChanged(bpmem.tevregs[num].high.type, num);
}
break;
default:
switch(addr&0xF0) {
case 0x30:
{
int tc = addr&0x1;
int stage = (addr>>1)&0x7;
TCoordInfo &tci = bpmem.texcoords[stage];
//TCInfo &t = (tc?tci.s:tc.t);
// cylindric wrapping here
//dev->SetRenderState(D3DRS_WRAP0+stage, D3DWRAPCOORD_0);
}
break;
switch (addr&0xF0)
{
case 0x10: // tevindirect 0-15
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PixelShaderManager::SetTevIndirectChanged(addr - 0x10);
}
break;
case 0x30:
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PixelShaderManager::SetTexDimsChanged((addr >> 1) & 0x7);
}
break;
case 0xC0:
case 0xD0:
if (changes)
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
// PixelShaderMngr::SetTevCombinerChanged((addr&0x1f)/2);
PixelShaderManager::SetTevCombinerChanged((addr & 0x1f)/2);
}
break;
case 0xE0:
if (addr<0xe8)
{
if (addr&1)
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
static int lastRGBA[2][4] = {
{0xEEEEEEEE, 0xEEEEEEEE, 0xEEEEEEEE, 0xEEEEEEEE},
{0xEEEEEEEE, 0xEEEEEEEE, 0xEEEEEEEE, 0xEEEEEEEE}
};
//Terrible hack
//The reason is that there are two sets of registers
//overloaded here...
int num = (addr >> 1) & 0x3;
int type = bpmem.tevregs[num].high.type;
int colorbase = type ? PS_CONST_KCOLORS : PS_CONST_COLORS;
int r=bpmem.tevregs[num].low.a, a=bpmem.tevregs[num].low.b;
int b=bpmem.tevregs[num].high.a, g=bpmem.tevregs[num].high.b;
int rgba = ((a<<24) | (r << 16) | (g << 8) | b) & 0xFCFCFCFC; //let's not detect minimal changes
if (rgba != lastRGBA[type][num])
{
VertexManager::Flush();
lastRGBA[type][num] = rgba;
float temp[4] = {
r/255.0f, g/255.0f, b/255.0f, a/255.0f
};
D3D::dev->SetPixelShaderConstantF(colorbase + num, temp, 1);
}
}
}
break;
case 0x20:
case 0x80:
case 0x90:
case 0xA0:
case 0xB0:
default:
if (changes)
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
}
case 0x20:
case 0x80:
case 0x90:
case 0xA0:
case 0xB0:
default:
break;
}
break;
}
break;
}
}
// __________________________________________________________________________________________________
// LoadBPReg
//
void LoadBPReg(u32 value0)
{
DVSTARTPROFILE();
//handle the mask register
int opcode = value0 >> 24;
int oldval = ((u32*)&bpmem)[opcode];
int newval = (((u32*)&bpmem)[opcode] & ~bpmem.bpMask) | (value0 & bpmem.bpMask);
int changes = (oldval ^ newval) & 0xFFFFFF;
//reset the mask register
if(opcode != 0xFE)
bpmem.bpMask = 0xFFFFFF;
switch (opcode)
{
case 0x45: //GXSetDrawDone
VertexManager::Flush();
switch (value0 & 0xFF)
{
case 0x02:
g_VideoInitialize.pSetPEFinish(); // may generate interrupt
DebugLog("GXSetDrawDone SetPEFinish (value: 0x%02X)", (value0 & 0xFFFF));
break;
default:
DebugLog("GXSetDrawDone ??? (value 0x%02X)", (value0 & 0xFFFF));
break;
}
break;
case BPMEM_PE_TOKEN_ID:
g_VideoInitialize.pSetPEToken(static_cast<u16>(value0 & 0xFFFF), FALSE);
DebugLog("SetPEToken 0x%04x", (value0 & 0xFFFF));
break;
case BPMEM_PE_TOKEN_INT_ID:
g_VideoInitialize.pSetPEToken(static_cast<u16>(value0 & 0xFFFF), TRUE);
DebugLog("SetPEToken + INT 0x%04x", (value0 & 0xFFFF));
break;
case 0x67: // set gp metric?
break;
case 0x52:
{
VertexManager::Flush();
((u32*)&bpmem)[opcode] = newval;
RECT rc = {
(LONG)(bpmem.copyTexSrcXY.x*Renderer::GetXScale()),
(LONG)(bpmem.copyTexSrcXY.y*Renderer::GetYScale()),
(LONG)((bpmem.copyTexSrcXY.x+bpmem.copyTexSrcWH.x)*Renderer::GetXScale()),
(LONG)((bpmem.copyTexSrcXY.y+bpmem.copyTexSrcWH.y)*Renderer::GetYScale())
};
UPE_Copy PE_copy;
PE_copy.Hex = bpmem.triggerEFBCopy;
// clamp0
// clamp1
// target_pixel_format
// gamma
// scale_something
// clear
// frame_to_field
// copy_to_xfb
// ???: start Mem to/from EFB transfer
/* bool bMip = false; // ignored
if (bpmem.triggerEFBCopy & EFBCOPY_GENERATEMIPS)
bMip = true;*/
if (PE_copy.copy_to_xfb == 0) // bpmem.triggerEFBCopy & EFBCOPY_EFBTOTEXTURE)
{
// EFB to texture
// for some reason it sets bpmem.zcontrol.pixel_format to PIXELFMT_Z24 every time a zbuffer format is given as a dest to GXSetTexCopyDst
TextureCache::CopyEFBToRenderTarget(bpmem.copyTexDest<<5, &rc);
}
else
{
// EFB to XFB
// MessageBox(0, "WASDF", 0, 0);
Renderer::SwapBuffers();
DebugLog("Renderer::SwapBuffers()");
g_VideoInitialize.pCopiedToXFB();
}
// clearing
if (PE_copy.clear) // bpmem.triggerEFBCopy & EFBCOPY_CLEAR)
{
// it seems that the GC is able to alpha blend on color-fill
// we cant do that so if alpha is != 255 we skip it
// clear color
u32 clearColor = (bpmem.clearcolorAR<<16)|bpmem.clearcolorGB;
if (bpmem.blendmode.colorupdate)
{
D3DRECT drc;
drc.x1 = rc.left;
drc.x2 = rc.right;
drc.y1 = rc.top;
drc.y2 = rc.bottom;
//D3D::dev->Clear(1, &drc, D3DCLEAR_STENCIL|D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,clearColor,1.0f,0);
//if ((clearColor>>24) == 255)
D3D::dev->ColorFill(D3D::GetBackBufferSurface(), &rc, clearColor);
}
else
{
// TODO:
// bpmem.blendmode.alphaupdate
// bpmem.blendmode.colorupdate
// i dunno how to implement a clear on alpha only or color only
}
// clear z-buffer
if (bpmem.zmode.updateenable)
{
float clearZ = (float)bpmem.clearZValue / float(0xFFFFFF);
if (clearZ > 1.0f) clearZ = 1.0f;
if (clearZ < 0.0f) clearZ = 0.0f;
D3D::dev->Clear(0, 0, D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0, clearZ, 0);
}
}
}
break;
case 0x65: //GXLoadTlut
{
VertexManager::Flush();
((u32*)&bpmem)[opcode] = newval;
u32 tlutTMemAddr = (value0&0x3FF)<<9;
u32 tlutXferCount = (value0&0x1FFC00)>>5;
//do the transfer!!
memcpy(texMem + tlutTMemAddr, g_VideoInitialize.pGetMemoryPointer((bpmem.tlutXferSrc&0xFFFFF)<<5), tlutXferCount);
// TODO(ector) : kill all textures that use this palette
// Not sure if it's a good idea, though. For now, we hash texture palettes
}
break;
}
//notify the video handling so it can update render states
BPWritten(opcode, changes, newval);
((u32*)&bpmem)[opcode] = newval;
}
void BPReload()
{
for (int i=0; i<254; i++)
BPWritten(i, 0xFFFFFF, ((u32*)&bpmem)[i]);
}
void ActivateTextures()
{
for (int i = 0; i < 8; i++)
@ -821,5 +746,3 @@ void ActivateTextures()
textureChanged[i] = false;
}
}

View File

@ -19,7 +19,6 @@
#include "CPStructs.h"
#include "XFStructs.h"
#include "TransformEngine.h"
#include "VertexManager.h"
#include "VertexLoader.h"
@ -27,7 +26,7 @@
void CPUpdateMatricesA()
{
float *flipmem = (float *)xfmem;
const float *flipmem = (const float *)xfmem;
CTransformEngine::SetPosNormalMatrix(
flipmem + MatrixIndexA.PosNormalMtxIdx * 4, //CHECK
flipmem + 0x400 + 3 * (MatrixIndexA.PosNormalMtxIdx & 31)); //CHECK

View File

@ -24,7 +24,7 @@
namespace D3D
{
LPDIRECT3DVERTEXSHADER9 CompileVShader(const char *code, int len)
LPDIRECT3DVERTEXSHADER9 CompileVertexShader(const char *code, int len)
{
//try to compile
LPD3DXBUFFER shaderBuffer = 0;
@ -43,8 +43,7 @@ LPDIRECT3DVERTEXSHADER9 CompileVShader(const char *code, int len)
std::string hello = (char*)errorBuffer->GetBufferPointer();
hello += "\n\n";
hello += code;
if (g_Config.bShowShaderErrors)
MessageBox(0, hello.c_str(), "Error compiling vertex shader", MB_ICONERROR);
MessageBox(0, hello.c_str(), "Error compiling vertex shader", MB_ICONERROR);
vShader = 0;
}
else if (SUCCEEDED(hr))
@ -55,8 +54,7 @@ LPDIRECT3DVERTEXSHADER9 CompileVShader(const char *code, int len)
hr = D3D::dev->CreateVertexShader((DWORD *)shaderBuffer->GetBufferPointer(), &vShader);
if (FAILED(hr) || vShader == 0)
{
if (g_Config.bShowShaderErrors)
MessageBox(0,code,(char*)errorBuffer->GetBufferPointer(),MB_ICONERROR);
MessageBox(0, code, (char*)errorBuffer->GetBufferPointer(),MB_ICONERROR);
}
}
@ -69,7 +67,7 @@ LPDIRECT3DVERTEXSHADER9 CompileVShader(const char *code, int len)
return vShader;
}
LPDIRECT3DPIXELSHADER9 CompilePShader(const char *code, int len)
LPDIRECT3DPIXELSHADER9 CompilePixelShader(const char *code, int len)
{
LPD3DXBUFFER shaderBuffer = 0;
LPD3DXBUFFER errorBuffer = 0;
@ -83,8 +81,7 @@ LPDIRECT3DPIXELSHADER9 CompilePShader(const char *code, int len)
std::string hello = (char*)errorBuffer->GetBufferPointer();
hello += "\n\n";
hello += code;
if (g_Config.bShowShaderErrors)
MessageBox(0, hello.c_str(), "Error compiling pixel shader", MB_ICONERROR);
MessageBox(0, hello.c_str(), "Error compiling pixel shader", MB_ICONERROR);
pShader = 0;
}
else
@ -93,8 +90,7 @@ LPDIRECT3DPIXELSHADER9 CompilePShader(const char *code, int len)
HRESULT hr = D3D::dev->CreatePixelShader((DWORD *)shaderBuffer->GetBufferPointer(), &pShader);
if (FAILED(hr) || pShader == 0)
{
if (g_Config.bShowShaderErrors)
MessageBox(0,"damn","error creating pixelshader",MB_ICONERROR);
MessageBox(0, "damn", "error creating pixelshader", MB_ICONERROR);
}
}
@ -106,4 +102,5 @@ LPDIRECT3DPIXELSHADER9 CompilePShader(const char *code, int len)
return pShader;
}
}
} // namespace

View File

@ -21,6 +21,6 @@
namespace D3D
{
LPDIRECT3DVERTEXSHADER9 CompileVShader(const char *code, int len);
LPDIRECT3DPIXELSHADER9 CompilePShader(const char *code, int len);
LPDIRECT3DVERTEXSHADER9 CompileVertexShader(const char *code, int len);
LPDIRECT3DPIXELSHADER9 CompilePixelShader(const char *code, int len);
}

View File

@ -83,7 +83,7 @@ namespace D3D
HFONT hFont = CreateFont(nHeight, 0, 0, 0, dwBold, 0,
FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
VARIABLE_PITCH, "Courier New");
VARIABLE_PITCH, "Tahoma");
if (NULL == hFont)
return E_FAIL;

View File

@ -1,92 +0,0 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "stdafx.h"
#include "DecodedVArray.h"
#include "main.h"
DecodedVArray::DecodedVArray()
{
Zero();
}
DecodedVArray::~DecodedVArray()
{
Destroy();
}
void DecodedVArray::Zero()
{
size = 0;
count = 0;
components = 0;
positions = 0;
posMtxInds = 0;
for (int i=0; i<3; i++)
normals[i] = 0;
for (int i=0; i<2; i++)
colors[i] = 0;
for (int i=0; i<8; i++)
{
texMtxInds[i] = 0;
uvs[i] = 0;
}
}
void DecodedVArray::Destroy()
{
//,,
delete [] positions;
delete [] posMtxInds;
for (int i=0; i<3; i++)
delete [] normals[i];
for (int i=0; i<2; i++)
delete [] colors[i];
for (int i=0; i<8; i++)
{
delete [] uvs[i];
delete [] texMtxInds[i];
}
Zero();
}
void DecodedVArray::Create(int _size, int pmcount, int tmcount, int nrmcount, int colcount, int tccount)
{
size = _size;
// position matrix indices
if (pmcount)
posMtxInds = new DecMtxInd[size];
// texture matrix indices
if (tmcount)
for (int i=0; i<tmcount; i++)
texMtxInds[i] = new DecMtxInd[size];
// positions (always)
positions = new DecPos[size];
// normals
if (nrmcount)
for (int i=0; i<nrmcount; i++)
normals[i] = new DecNormal[size];
// colors
if (colcount)
for (int i=0; i<colcount; i++)
colors[i] = new DecColor[size];
if (tccount)
for (int i=0; i<tccount; i++)
uvs[i] = new DecUV[size];
}

View File

@ -1,114 +0,0 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _DECODED_VARRAY_H
#define _DECODED_VARRAY_H
#include "Vec3.h"
#include "Common.h"
typedef Vec3 DecPos;
typedef Vec3 DecNormal;
struct DecUV
{
float u,v;
};
typedef u32 DecColor;
typedef u8 DecMtxInd;
int ComputeVertexSize(u32 components);
//TODO(ector): Change the internal implementation to pack it tight according to components
// The tight packing will be fed directly to the gfx card in the mystic future.
class DecodedVArray
{
int size;
u32 components;
int vertexSize;
public:
int count;
DecodedVArray();
~DecodedVArray();
void SetComponents(u32 comps) {components = comps; vertexSize = ComputeVertexSize(components);
ComputeComponents(); }
u32 GetComponents() const {return components;}
void Create(int _size, int pmcount, int tmcount, int nrmcount, int colcount, int tccount);
void Zero();
void Destroy();
void Reset() {count=0;}
int GetSize() {return size;}
int GetCount() {return count;}
void Next() {count++;}
void SetPosNrmIdx(int i) {posMtxInds[count] = i;}
void SetTcIdx(int n, int i) {texMtxInds[n][count] = i;}
void SetPosX(float x) {positions[count].x=x;}
void SetPosY(float y) {positions[count].y=y;}
void SetPosZ(float z) {positions[count].z=z;}
void SetNormalX(int n,float x) {normals[n][count].x=x;}
void SetNormalY(int n,float y) {normals[n][count].y=y;}
void SetNormalZ(int n,float z) {normals[n][count].z=z;}
void SetU(int n, float u) {uvs[n][count].u = u;}
void SetV(int n, float v) {uvs[n][count].v = v;}
void SetPosition(float x, float y, float z) {
positions[count].x=x;
positions[count].y=y;
positions[count].z=z;
}
void SetNormal(int n, float x, float y, float z) {
normals[n][count].x=x;
normals[n][count].y=y;
normals[n][count].z=z;
}
void SetColor(int n, u32 c)
{
colors[n][count] = c;
}
void SetUV(int n, float u, float v) {
uvs[n][count].u=u;
uvs[n][count].v=v;
}
void ComputeComponents() {
hasPosMatIdx = (components & (1 << 1)) != 0;
for(int i = 0; i < 8; i++)
hasTexMatIdx[i] = (components & (1 << (i + 2))) != 0;
hasNrm = (components & (1 << 10)) != 0;
}
const DecPos &GetPos(int n) const { return positions[n]; }
const DecNormal &GetNormal(int i, int n) const { return normals[i][n]; }
const DecColor &GetColor(int i, int n) const { return colors[i][n]; }
const DecUV &GetUV(int i, int n) const { return uvs[i][n]; }
const DecMtxInd &GetPosMtxInd(int n) const { return posMtxInds[n]; }
const DecMtxInd &GetTexMtxInd(int i, int n) const { return texMtxInds[i][n]; }
//private:
DecPos *positions;
DecNormal *normals[3];
DecColor *colors[2];
DecUV *uvs[8];
DecMtxInd *posMtxInds;
DecMtxInd *texMtxInds[8];
// Component data
bool hasPosMatIdx, hasTexMatIdx[8], hasNrm;
};
#endif

View File

@ -52,6 +52,7 @@ namespace EmuWindow
break;
case WM_CLOSE:
exit(0);
return 0;
case WM_DESTROY:

View File

@ -1,3 +1,4 @@
// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
@ -21,7 +22,7 @@
#include "x64Emitter.h"
#include "ABI.h"
#include "MemoryUtil.h"
#include "VertexShader.h"
#include "VertexShaderGen.h"
#include "CPMemory.h"
#include "NativeVertexFormat.h"
@ -29,7 +30,6 @@
class D3DVertexFormat : public NativeVertexFormat
{
PortableVertexDeclaration vtx_decl;
LPDIRECT3DVERTEXDECLARATION9 d3d_decl;
public:
@ -39,7 +39,6 @@ public:
virtual void SetupVertexPointers() const;
};
NativeVertexFormat *NativeVertexFormat::Create()
{
return new D3DVertexFormat();
@ -58,7 +57,6 @@ D3DVertexFormat::~D3DVertexFormat()
}
}
D3DDECLTYPE VarToD3D(VarType t)
{
static const D3DDECLTYPE lookup[5] =
@ -74,6 +72,8 @@ D3DDECLTYPE VarToD3D(VarType t)
void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
{
vertex_stride = _vtx_decl.stride;
D3DVERTEXELEMENT9 *elems = new D3DVERTEXELEMENT9[32];
memset(elems, 0, sizeof(D3DVERTEXELEMENT9) * 32);
@ -123,8 +123,9 @@ void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
}
}
if (vtx_decl.posmtx_offset != -1)
if (_vtx_decl.posmtx_offset != -1)
{
PanicAlert("boo %i", _vtx_decl.posmtx_offset);
// glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (void *)vtx_decl.posmtx_offset);
elems[elem_idx].Offset = _vtx_decl.posmtx_offset;
elems[elem_idx].Usage = D3DDECLUSAGE_BLENDINDICES;
@ -132,6 +133,11 @@ void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
++elem_idx;
}
// End marker
elems[elem_idx].Stream = 0xff;
elems[elem_idx].Type = D3DDECLTYPE_UNUSED;
++elem_idx;
if (FAILED(D3D::dev->CreateVertexDeclaration(elems, &d3d_decl)))
{
PanicAlert("Failed to create D3D vertex declaration!");

View File

@ -1,525 +0,0 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "PixelShader.h"
#include "BPStructs.h"
#include "XFStructs.h"
/*
old tev->pixelshader notes
color for this stage (alpha, color) is given by bpmem.tevorders[0].colorchan0
konstant for this stage (alpha, color) is given by bpmem.tevksel
inputs are given by bpmem.combiners[0].colorC.a/b/c/d << could be current chan color
according to GXTevColorArg table above
output is given by .outreg
tevtemp is set according to swapmodetables and
*/
const float epsilon = 1.0f/255.0f;
const char *tevKSelTableC[] =
{
"1,1,1", //KCSEL_1 = 0x00
"0.875,0.875,0.875",//KCSEL_7_8 = 0x01
"0.75,0.75,0.75", //KCSEL_3_4 = 0x02
"0.625,0.625,0.625",//KCSEL_5_8 = 0x03
"0.5,0.5,0.5", //KCSEL_1_2 = 0x04
"0.375,0.375,0.375",//KCSEL_3_8 = 0x05
"0.25,0.25,0.25", //KCSEL_1_4 = 0x06
"0.125,0.125,0.125",//KCSEL_1_8 = 0x07
"ERROR", //0x08
"ERROR", //0x09
"ERROR", //0x0a
"ERROR", //0x0b
"k0.rgb",//KCSEL_K0 = 0x0C
"k1.rgb",//KCSEL_K1 = 0x0D
"k2.rgb",//KCSEL_K2 = 0x0E
"k3.rgb",//KCSEL_K3 = 0x0F
"k0.rrr",//KCSEL_K0_R = 0x10
"k1.rrr",//KCSEL_K1_R = 0x11
"k2.rrr",//KCSEL_K2_R = 0x12
"k3.rrr",//KCSEL_K3_R = 0x13
"k0.ggg",//KCSEL_K0_G = 0x14
"k1.ggg",//KCSEL_K1_G = 0x15
"k2.ggg",//KCSEL_K2_G = 0x16
"k3.ggg",//KCSEL_K3_G = 0x17
"k0.bbb",//KCSEL_K0_B = 0x18
"k1.bbb",//KCSEL_K1_B = 0x19
"k2.bbb",//KCSEL_K2_B = 0x1A
"k3.bbb",//KCSEL_K3_B = 0x1B
"k0.aaa",//KCSEL_K0_A = 0x1C
"k1.aaa",//KCSEL_K1_A = 0x1D
"k2.aaa",//KCSEL_K2_A = 0x1E
"k3.aaa",//KCSEL_K3_A = 0x1F
};
const char *tevKSelTableA[] =
{
"1", //KASEL_1 = 0x00
"0.875",//KASEL_7_8 = 0x01
"0.75", //KASEL_3_4 = 0x02
"0.625",//KASEL_5_8 = 0x03
"0.5", //KASEL_1_2 = 0x04
"0.375",//KASEL_3_8 = 0x05
"0.25", //KASEL_1_4 = 0x06
"0.125",//KASEL_1_8 = 0x07
"ERROR",//0x08
"ERROR",//0x09
"ERROR",//0x0a
"ERROR",//0x0b
"ERROR",//0x0c
"ERROR",//0x0d
"ERROR",//0x0e
"ERROR",//0x0f
"k0.r", //KASEL_K0_R = 0x10
"k1.r", //KASEL_K1_R = 0x11
"k2.r", //KASEL_K2_R = 0x12
"k3.r", //KASEL_K3_R = 0x13
"k0.g", //KASEL_K0_G = 0x14
"k1.g", //KASEL_K1_G = 0x15
"k2.g", //KASEL_K2_G = 0x16
"k3.g", //KASEL_K3_G = 0x17
"k0.b", //KASEL_K0_B = 0x18
"k1.b", //KASEL_K1_B = 0x19
"k2.b", //KASEL_K2_B = 0x1A
"k3.b", //KASEL_K3_B = 0x1B
"k0.a", //KASEL_K0_A = 0x1C
"k1.a", //KASEL_K1_A = 0x1D
"k2.a", //KASEL_K2_A = 0x1E
"k3.a", //KASEL_K3_A = 0x1F
};
const char *tevScaleTable[] =
{
"1", //SCALE_1
"2", //SCALE_2
"4", //SCALE_4
"0.5", //DIVIDE_2
};
const char *tevBiasTable[] =
{
"", //ZERO,
"+0.5", //ADD_HALF,
"-0.5", //SUB_HALF,
"", //WTF? seen in shadow2
};
const char *tevOpTable[] =
{
"+", //ADD = 0,
"-", //SUB = 1,
};
const char *tevCompOpTable[] =
{
">",
"==",
};
#define TEV_COMP_R8 0
#define TEV_COMP_GR16 1
#define TEV_COMP_BGR24 2
#define TEV_COMP_RGB8 3
const char *tevCInputTable[] =
{
"prev.rgb", //CPREV,
"prev.aaa", //APREV,
"c0.rgb", //C0,
"c0.aaa", //A0,
"c1.rgb", //C1,
"c1.aaa", //A1,
"c2.rgb", //C2,
"c2.aaa", //A2,
"textemp.rgb", //TEXC,
"textemp.aaa", //TEXA,
"rastemp.rgb", //RASC,
"rastemp.aaa", //RASA,
"float3(1,1,1)", //ONE,
"float3(.5,.5,.5)", //HALF,
"konsttemp.rgb", //KONST,
"float3(0,0,0)", //ZERO
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
};
const char *tevCInputTable2[] =
{
"prev", //CPREV,
"(prev.aaa)", //APREV,
"c0", //C0,
"(c0.aaa)", //A0,
"c1", //C1,
"(c1.aaa)", //A1,
"c2", //C2,
"(c2.aaa)", //A2,
"textemp", //TEXC,
"(textemp.aaa)", //TEXA,
"rastemp", //RASC,
"(rastemp.aaa)", //RASA,
"float3(1,1,1)", //ONE,
"float3(.5,.5,.5)", //HALF,
"konsttemp", //KONST,
"float3(0,0,0)", //ZERO
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
};
const char *tevAInputTable[] =
{
"prev.a", //APREV,
"c0.a", //A0,
"c1.a", //A1,
"c2.a", //A2,
"textemp.a", //TEXA,
"rastemp.a", //RASA,
"konsttemp.a", //KONST, (hw1 had quarter)
"0.0", //ZERO
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
};
const char *tevAInputTable1[] =
{
"prev.r", //APREV,
"c0.r", //A0,
"c1.r", //A1,
"c2.r", //A2,
"textemp.r", //TEXA,
"rastemp.r", //RASA,
"konsttemp.r", //KONST, (hw1 had quarter)
"0.0", //ZERO
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
};
const char *tevAInputTable2[] =
{
"prev", //APREV,
"c0", //A0,
"c1", //A1,
"c2", //A2,
"textemp", //TEXA,
"rastemp", //RASA,
"konsttemp", //KONST, (hw1 had quarter)
"float4(0,0,0,0)",//ZERO
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
"PADERROR", "PADERROR", "PADERROR", "PADERROR",
};
const char *tevRasTable[] =
{
"colors[0]",//RAS1_CC_0 0x00000000 /* color channel 0 */
"colors[1]",//RAS1_CC_1 0x00000001 /* color channel 1 */
"ERROR", //2
"ERROR", //3
"ERROR", //4
"alphabump", //RAS1_CC_B 0x00000005 /* indirect texture bump alpha */ //green cuz unsupported
"(alphabump*(255.0f/248.0f))", //RAS1_CC_BN 0x00000006 /* ind tex bump alpha, normalized 0-255 *///green cuz unsupported
"float4(0,0,0,0)", //RAS1_CC_Z 0x00000007 /* set color value to zero */
};
const char *tevCOutputTable[] = { "prev.rgb", "c0.rgb", "c1.rgb", "c2.rgb" };
const char *tevAOutputTable[] = { "prev.a", "c0.a", "c1.a", "c2.a" };
const char *tevIndAlphaSel[] = {"", "x", "y", "z"};
const char *tevIndAlphaScale[] = {"", "*32","*16","*8"};
const char *tevIndBiasField[] = {"", "x", "y", "xy", "z", "xz", "yz", "xyz"}; // indexed by bias
const char *tevIndBiasAdd[] = {"-128.0f", "1.0f", "1.0f", "1.0f" }; // indexed by fmt
const char *tevIndWrapStart[] = {"0", "256", "128", "64", "32", "16", "0.001" };
const char *tevIndFmtScale[] = {"255.0f", "31.0f", "15.0f", "8.0f" };
const char *tevTexFuncs[] =
{
"tex2D",
"tex2Dproj"
};
const char *alphaRef[2] =
{
"alphaRef.x",
"alphaRef.y"
};
char text[65536];
#define WRITE p+=sprintf
void WriteStage(char *&p, int n);
void WriteAlphaTest(char *&p);
char *swapColors = "rgba";
char swapModeTable[4][5];
void BuildSwapModeTable()
{
for (int i = 0; i < 4; i++)
{
swapModeTable[i][0] = swapColors[bpmem.tevksel[i*2].swap1];
swapModeTable[i][1] = swapColors[bpmem.tevksel[i*2].swap2];
swapModeTable[i][2] = swapColors[bpmem.tevksel[i*2+1].swap1];
swapModeTable[i][3] = swapColors[bpmem.tevksel[i*2+1].swap2];
swapModeTable[i][4] = 0;
}
}
const char *GeneratePixelShader()
{
BuildSwapModeTable();
int numStages = bpmem.genMode.numtevstages + 1;
int numTexgen = bpmem.genMode.numtexgens;
int numSamplers = 8;
char *p = text;
WRITE(p,"//Pixel Shader for TEV stages\n\
//%i TEV stages, %i texgens, %i IND stages, %i COL channels\n",
bpmem.genMode.numtevstages,bpmem.genMode.numtexgens,bpmem.genMode.numindstages,bpmem.genMode.numcolchans);
//write kcolor declarations
for (int i = 0; i < 4; i++) {
if(i < 3) {
WRITE(p,"float4 k%i : register(c%i);\n\
float4 color%i : register(c%i);\n",i,PS_CONST_KCOLORS+i, i,PS_CONST_COLORS+i+1);
} else {
WRITE(p,"float4 k%i : register(c%i);\n",i,PS_CONST_KCOLORS+i);
}
}
WRITE(p,"float constalpha : register(c%i);\n\
float2 alphaRef : register(c%i);\n\n\
sampler samp[%i] : register(s0);\n\n\
float4 main(in float4 colors[2] : COLOR0",PS_CONST_CONSTALPHA,PS_CONST_ALPHAREF,numSamplers);
if (numTexgen)
WRITE(p,", float4 uv[%i] : TEXCOORD0",numTexgen);
else
WRITE(p,", float4 uv[1] : TEXCOORD0"); //HACK
WRITE(p,") : COLOR\n\
{\n\
float4 c0=color0,c1=color1,c2=color2,prev=float4(0.0f,0.0f,0.0f,0.0f),textemp,rastemp,konsttemp;\n\
float3 comp16 = float3(1,255,0), comp24 = float3(1,255,255*255);\n\
\n");
for (int i = 0; i < numStages; i++)
WriteStage(p,i); //build the equation for this stage
WriteAlphaTest(p);
/* see GL shader generator - this is Donko's hack
if (bpmem.dstalpha.enable)
WRITE(p," return float4(prev.rgb,constalpha.x);\n");
else
*/
WRITE(p," return prev;\n");
WRITE(p,"}\n\0");
return text;
}
void WriteStage(char *&p, int n)
{
const char *rasswap = swapModeTable[bpmem.combiners[n].alphaC.rswap];
const char *texswap = swapModeTable[bpmem.combiners[n].alphaC.tswap];
int texfun = xfregs.texcoords[n].texmtxinfo.projection;
WRITE(p,"rastemp=%s.%s;\n",tevRasTable[bpmem.tevorders[n/2].getColorChan(n&1)],rasswap);
if (bpmem.tevorders[n/2].getEnable(n&1))
WRITE(p,"textemp=%s(samp[%i],uv[%i]).%s;\n",
tevTexFuncs[texfun],
bpmem.tevorders[n/2].getTexMap(n&1),
bpmem.tevorders[n/2].getTexCoord(n&1),texswap);
else
WRITE(p,"textemp=float4(1,1,1,1);\n");
int kc = bpmem.tevksel[n/2].getKC(n&1);
int ka = bpmem.tevksel[n/2].getKA(n&1);
WRITE(p,"konsttemp=float4(%s,%s);\n",tevKSelTableC[kc],tevKSelTableA[ka]);
TevStageCombiner::ColorCombiner &cc = bpmem.combiners[n].colorC;
TevStageCombiner::AlphaCombiner &ac = bpmem.combiners[n].alphaC;
WRITE(p,"float4(%s,%s)=", tevCOutputTable[cc.dest], tevAOutputTable[ac.dest]);
//////////////////////////////////////////////////////////////////////////
//start of color
//////////////////////////////////////////////////////////////////////////
WRITE(p,"float4(\n");
if (cc.bias != TB_COMPARE)
{
//normal color combiner goes here
WRITE(p," %s*(%s%s",tevScaleTable[cc.shift],tevCInputTable[cc.d],tevOpTable[cc.op]);
WRITE(p,"(lerp(%s,%s,%s)%s)),\n",
tevCInputTable[cc.a],tevCInputTable[cc.b],
tevCInputTable[cc.c],tevBiasTable[cc.bias]);
}
else
{
//compare color combiner goes here
switch(cc.shift) // yep comparemode stored here :P
{
case TEV_COMP_R8:
if (cc.op == 0) //equality check needs tolerance, fp in gpu has drawbacks :(
WRITE(p," %s + ((%s.r > %s.r) ? %s : float3(0,0,0)),\n",
tevCInputTable[cc.d],tevCInputTable2[cc.a],
tevCInputTable2[cc.b],tevCInputTable[cc.c]);
else
WRITE(p," %s + (abs(%s.r - %s.r)<%f ? %s : float3(0,0,0)),\n",
tevCInputTable[cc.d],tevCInputTable2[cc.a],
tevCInputTable2[cc.b],epsilon,tevCInputTable[cc.c]);
break;
default:
WRITE(p,"float3(0,0,0),\n");
break;
}
}
//end of color
//////////////////////////////////////////////////////////////////////////
//start of alpha
//////////////////////////////////////////////////////////////////////////
if (ac.bias != TB_COMPARE)
{
//normal alpha combiner goes here
WRITE(p," %s*(%s%s",tevScaleTable[ac.shift],tevAInputTable[ac.d],tevOpTable[ac.op]);
WRITE(p,"lerp(%s,%s,%s) %s)\n",
tevAInputTable[ac.a],tevAInputTable[ac.b],
tevAInputTable[ac.c],tevBiasTable[ac.bias]);
}
else
{
int cmp = (ac.shift<<1)|ac.op|8; // comparemode stored here
const char **inputTable = NULL;
inputTable = (cmp == TEVCMP_R8_GT || cmp == TEVCMP_R8_EQ) ? tevAInputTable1 : tevAInputTable;
//compare alpha combiner goes here
switch(cmp) {
case TEVCMP_R8_GT:
case TEVCMP_A8_GT:
WRITE(p," %s + ((%s > %s) ? %s : 0)\n",
tevAInputTable[ac.d], inputTable[ac.a], inputTable[ac.b], tevAInputTable[ac.c]);
break;
case TEVCMP_R8_EQ:
case TEVCMP_A8_EQ:
WRITE(p," %s + (abs(%s - %s)<%f ? %s : 0)\n",
tevAInputTable[ac.d], inputTable[ac.a], inputTable[ac.b],epsilon,tevAInputTable[ac.c]);
break;
case TEVCMP_GR16_GT: // 16 bit compares: 255*g+r (probably used for ztextures, so make sure in ztextures, g is the most significant byte)
case TEVCMP_BGR24_GT: // 24 bit compares: 255*255*b+255*g+r
WRITE(p," %s + (( dot(%s.rgb-%s.rgb, comp%s) > 0) ? %s : 0)\n",
tevAInputTable[ac.d],tevAInputTable2[ac.a], tevAInputTable2[ac.b], cmp==TEVCMP_GR16_GT?"16":"24", tevAInputTable[ac.c]);
break;
case TEVCMP_GR16_EQ:
case TEVCMP_BGR24_EQ:
WRITE(p," %s + (abs(dot(%s.rgb - %s.rgb, comp%s))<%f ? %s : 0)\n",
tevAInputTable[ac.d],tevAInputTable2[ac.a], tevAInputTable2[ac.b],cmp==TEVCMP_GR16_EQ?"16":"24",epsilon,tevAInputTable[ac.c]);
break;
default:
WRITE(p,"0)\n");
break;
}
}
WRITE(p, ");");
if (ac.clamp)
WRITE(p, "%s = clamp(%s, 0.0f, 1.0f);\n", tevAOutputTable[ac.dest], tevAOutputTable[ac.dest]);
WRITE(p, "\n");
}
void WriteAlphaCompare(char *&p, int num, int comp)
{
WRITE(p," res%i = ",num);
switch(comp) {
case ALPHACMP_ALWAYS: WRITE(p,"0;\n"); break;
case ALPHACMP_NEVER: WRITE(p,"1;\n"); break;
case ALPHACMP_LEQUAL: WRITE(p,"prev.a - %s.x;\n",alphaRef[num]); break;
case ALPHACMP_LESS: WRITE(p,"prev.a - %s.x + %f;\n",alphaRef[num],epsilon*2);break;
case ALPHACMP_GEQUAL: WRITE(p,"%s - prev.a;\n",alphaRef[num]); break;
case ALPHACMP_GREATER: WRITE(p,"%s - prev.a + %f;\n",alphaRef[num],epsilon*2);break;
case ALPHACMP_EQUAL: WRITE(p,"abs(%s-prev.a)-%f;\n",alphaRef[num],epsilon*2); break;
case ALPHACMP_NEQUAL: WRITE(p,"%f-abs(%s-prev.a);\n",epsilon*2,alphaRef[num]); break;
}
}
void WriteAlphaTest(char *&p)
{
AlphaOp op = (AlphaOp)bpmem.alphaFunc.logic;
Compare comp[2] = {(Compare)bpmem.alphaFunc.comp0,(Compare)bpmem.alphaFunc.comp1};
//first kill all the simple cases
if (op == ALPHAOP_AND && (comp[0] == COMPARE_ALWAYS && comp[1] == COMPARE_ALWAYS)) return;
if (op == ALPHAOP_OR && (comp[0] == COMPARE_ALWAYS || comp[1] == COMPARE_ALWAYS)) return;
for (int i = 0; i < 2; i++)
{
int one = i;
int other = 1-i;
switch(op) {
case ALPHAOP_XOR:
if (comp[one] == COMPARE_ALWAYS && comp[other] == COMPARE_NEVER) return;
break;
case ALPHAOP_XNOR:
if (comp[one] == COMPARE_ALWAYS && comp[other] == COMPARE_ALWAYS) return;
if (comp[one] == COMPARE_ALWAYS && comp[other] == COMPARE_NEVER) return;
break;
}
}
//Ok, didn't get to do the easy way out :P
// do the general way
WRITE(p,"float res0, res1;\n");
WriteAlphaCompare(p, 0, bpmem.alphaFunc.comp0);
WriteAlphaCompare(p, 1, bpmem.alphaFunc.comp1);
WRITE(p,"res0 = max(res0, 0);\n");
WRITE(p,"res1 = max(res1, 0);\n");
//probably should use lookup textures for some of these :P
switch(bpmem.alphaFunc.logic) {
case ALPHAOP_AND: // if both are 0
WRITE(p,"clip(-(res0+res1)+%f);\n",epsilon);
break;
case ALPHAOP_OR: //if either is 0
WRITE(p,"clip(-res0*res1+%f);\n",epsilon*epsilon);
break;
case ALPHAOP_XOR:
//hmm, this might work:
WRITE(p,"res0=(res0>0?1:0)-.5;\n");
WRITE(p,"res1=(res1>0?1:0)-.5;\n");
WRITE(p,"clip(-res0*res1);\n",epsilon);
break;
case ALPHAOP_XNOR:
WRITE(p,"res0=(res0>0?1:0)-.5;\n");
WRITE(p,"res1=(res1>0?1:0)-.5;\n");
WRITE(p,"clip(res0*res1);\n",epsilon);
break;
}
}

View File

@ -1,30 +0,0 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#pragma once
#include "Common.h"
#include "D3DShader.h"
#define PS_CONST_COLORS 0
#define PS_CONST_KCOLORS 4
#define PS_CONST_CONSTALPHA 8
#define PS_CONST_ALPHAREF 9 // x,y
#define PS_CONST_INDMTXSTART 10
#define PS_CONST_INDSIZE 2
const char *GeneratePixelShader();

View File

@ -16,60 +16,44 @@
// http://code.google.com/p/dolphin-emu/
#include "D3DBase.h"
#include "D3DShader.h"
#include "Statistics.h"
#include "Utils.h"
#include "Profiler.h"
#include "PixelShaderGen.h"
#include "PixelShaderManager.h"
#include "PixelShaderCache.h"
#include "VertexLoader.h"
#include "BPMemory.h"
#include "XFMemory.h"
PShaderCache::PSCache PShaderCache::pshaders;
PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
//I hope we don't get too many hash collisions :p
//all these magic numbers are primes, it should help a bit
tevhash GetCurrentTEV()
void SetPSConstant4f(int const_number, float f1, float f2, float f3, float f4)
{
u32 hash = bpmem.genMode.numindstages + bpmem.genMode.numtevstages*11 + bpmem.genMode.numtexgens*8*17;
for (int i = 0; i < (int)bpmem.genMode.numtevstages+1; i++)
{
hash = _rotl(hash,3) ^ (bpmem.combiners[i].colorC.hex*13);
hash = _rotl(hash,7) ^ ((bpmem.combiners[i].alphaC.hex&0xFFFFFFFC)*3);
hash = _rotl(hash,9) ^ xfregs.texcoords[i].texmtxinfo.projection*451;
}
for (int i = 0; i < (int)bpmem.genMode.numtevstages/2+1; i++)
{
hash = _rotl(hash,13) ^ (bpmem.tevorders[i].hex*7);
}
for (int i = 0; i < 8; i++)
{
hash = _rotl(hash,3) ^ bpmem.tevksel[i].swap1;
hash = _rotl(hash,3) ^ bpmem.tevksel[i].swap2;
}
hash ^= bpmem.dstalpha.enable ^ 0xc0debabe;
hash = _rotl(hash,4) ^ bpmem.alphaFunc.comp0*7;
hash = _rotl(hash,4) ^ bpmem.alphaFunc.comp1*13;
hash = _rotl(hash,4) ^ bpmem.alphaFunc.logic*11;
return hash;
const float f[4] = {f1, f2, f3, f4};
D3D::dev->SetPixelShaderConstantF(const_number, f, 1);
}
void SetPSConstant4fv(int const_number, const float *f)
{
D3D::dev->SetPixelShaderConstantF(const_number, f, 1);
}
void PShaderCache::Init()
void PixelShaderCache::Init()
{
}
void PShaderCache::Shutdown()
void PixelShaderCache::Shutdown()
{
PSCache::iterator iter = pshaders.begin();
for (;iter!=pshaders.end();iter++)
PSCache::iterator iter = PixelShaders.begin();
for (; iter != PixelShaders.end(); iter++)
iter->second.Destroy();
pshaders.clear();
PixelShaders.clear();
}
void PShaderCache::SetShader()
void PixelShaderCache::SetShader()
{
if (D3D::GetShaderVersion() < 2)
return; // we are screwed
@ -77,12 +61,13 @@ void PShaderCache::SetShader()
static LPDIRECT3DPIXELSHADER9 lastShader = 0;
DVSTARTPROFILE();
tevhash currentHash = GetCurrentTEV();
PIXELSHADERUID uid;
GetPixelShaderId(uid, PixelShaderManager::GetTextureMask(), false, false);
PSCache::iterator iter;
iter = pshaders.find(currentHash);
iter = PixelShaders.find(uid);
if (iter != pshaders.end())
if (iter != PixelShaders.end())
{
iter->second.frameCount = frameCount;
PSCacheEntry &entry = iter->second;
@ -94,40 +79,39 @@ void PShaderCache::SetShader()
return;
}
const char *code = GeneratePixelShader();
LPDIRECT3DPIXELSHADER9 shader = D3D::CompilePShader(code, int(strlen(code)));
const char *code = GeneratePixelShader(PixelShaderManager::GetTextureMask(), false, false);
LPDIRECT3DPIXELSHADER9 shader = D3D::CompilePixelShader(code, (int)(strlen(code)));
if (shader)
{
//Make an entry in the table
PSCacheEntry newentry;
newentry.shader = shader;
newentry.frameCount = frameCount;
pshaders[currentHash] = newentry;
PixelShaders[uid] = newentry;
INCSTAT(stats.numPixelShadersCreated);
SETSTAT(stats.numPixelShadersAlive, (int)PixelShaders.size());
}
D3D::dev->SetPixelShader(shader);
INCSTAT(stats.numPixelShadersCreated);
SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size());
}
void PShaderCache::Cleanup()
void PixelShaderCache::Cleanup()
{
PSCache::iterator iter;
iter = pshaders.begin();
while (iter != pshaders.end())
iter = PixelShaders.begin();
while (iter != PixelShaders.end())
{
PSCacheEntry &entry = iter->second;
if (entry.frameCount < frameCount-30)
{
entry.Destroy();
iter = pshaders.erase(iter);
iter = PixelShaders.erase(iter);
}
else
{
iter++;
}
}
SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size());
SETSTAT(stats.numPixelShadersAlive, (int)PixelShaders.size());
}

View File

@ -22,14 +22,14 @@
#include <map>
#include "PixelShader.h"
#include "VertexShader.h"
#include "PixelShaderGen.h"
#include "VertexShaderGen.h"
typedef u32 tevhash;
tevhash GetCurrentTEV();
class PShaderCache
class PixelShaderCache
{
struct PSCacheEntry
{
@ -48,9 +48,9 @@ class PShaderCache
}
};
typedef std::map<tevhash, PSCacheEntry> PSCache;
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
static PSCache pshaders;
static PSCache PixelShaders;
public:
static void Init();

View File

@ -15,6 +15,7 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include <list>
#include <d3dx9.h>
#include "Common.h"
@ -30,16 +31,20 @@
#include "D3DPostprocess.h"
#include "D3DUtil.h"
#include "VertexShaderManager.h"
#include "VertexShaderCache.h"
#include "PixelShaderManager.h"
#include "VertexShaderCache.h"
#include "PixelShaderCache.h"
#include "TextureCache.h"
#include "Utils.h"
#include "EmuWindow.h"
#include <list>
float Renderer::m_x;
float Renderer::m_y;
float Renderer::m_width;
float Renderer::m_height;
float Renderer::xScale;
float Renderer::yScale;
float Renderer::m_x,Renderer::m_y,Renderer::m_width, Renderer::m_height, Renderer::xScale,Renderer::yScale;
std::vector<LPDIRECT3DBASETEXTURE9> Renderer::m_Textures;
DWORD Renderer::m_RenderStates[MaxRenderStates+46];
@ -50,18 +55,14 @@ DWORD Renderer::m_FVF;
#define NUMWNDRES 6
extern int g_Res[NUMWNDRES][2];
struct Message
{
Message(const std::string &msg, u32 dw) : message( msg ), dwTimeStamp( dw )
{
}
Message(const std::string &msg, u32 dw) : message(msg), dwTimeStamp(dw) { }
std::string message;
u32 dwTimeStamp;
};
static std::list<Message> s_listMsgs;
static std::list<Message> s_listMsgs;
void Renderer::Init(SVideoInitialize &_VideoInitialize)
{
@ -79,32 +80,44 @@ void Renderer::Init(SVideoInitialize &_VideoInitialize)
xScale = 640.0f / (float)vp.Width;
yScale = 480.0f / (float)vp.Height;
D3DXMATRIX mtx;
D3DXMatrixIdentity(&mtx);
D3D::dev->SetTransform(D3DTS_VIEW, &mtx);
D3D::dev->SetTransform(D3DTS_WORLD, &mtx);
float width = (float)D3D::GetDisplayWidth();
float height = (float)D3D::GetDisplayHeight();
xScale = width/640.0f;
yScale = height/480.0f;
/*
RECT rc =
{
(LONG)(m_x*xScale),
(LONG)(m_y*yScale),
(LONG)(m_width*xScale),
(LONG)(m_height*yScale)
};
*/
D3D::font.Init();
Initialize();
}
void Renderer::Shutdown(void)
void Renderer::Shutdown()
{
D3D::font.Shutdown();
D3D::EndFrame();
D3D::Close();
}
void Renderer::Initialize(void)
void Renderer::Initialize()
{
m_FVF = 0;
m_Textures.reserve(MaxTextureStages);
for (int i = 0; i < MaxTextureStages; i++)
m_Textures.push_back(NULL);
m_Textures.reserve( MaxTextureStages );
for ( int i = 0; i < MaxTextureStages; i++ )
{
m_Textures.push_back( NULL );
}
for (int i=0; i<8; i++)
{
for (int i = 0; i < 8; i++)
D3D::dev->SetSamplerState(i, D3DSAMP_MAXANISOTROPY, 16);
}
ReinitView();
Postprocess::Initialize();
Postprocess::BeginFrame();
@ -123,15 +136,15 @@ void Renderer::ProcessMessages()
int left = 25, top = 15;
std::list<Message>::iterator it = s_listMsgs.begin();
while( it != s_listMsgs.end() )
while(it != s_listMsgs.end())
{
int time_left = (int)(it->dwTimeStamp - timeGetTime());
int alpha = 255;
if(time_left<1024)
if (time_left<1024)
{
alpha=time_left>>2;
if(time_left<0) alpha=0;
if (time_left<0) alpha=0;
}
alpha <<= 24;
@ -162,28 +175,9 @@ void dumpMatrix(D3DXMATRIX &mtx)
}
}
void Renderer::ReinitView()
void Renderer::SwapBuffers()
{
D3DXMATRIX mtx;
D3DXMatrixIdentity(&mtx);
D3D::dev->SetTransform(D3DTS_VIEW,&mtx);
D3D::dev->SetTransform(D3DTS_WORLD,&mtx);
float width = (float)D3D::GetDisplayWidth();
float height = (float)D3D::GetDisplayHeight();
xScale = width/640.0f;
yScale = height/480.0f;
RECT rc =
{
(LONG)(m_x*xScale), (LONG)(m_y*yScale), (LONG)(m_width*xScale), (LONG)(m_height*yScale)
};
}
void Renderer::SwapBuffers(void)
{
// center window again
// Center window again.
if (EmuWindow::GetParentWnd())
{
RECT rcWindow;
@ -192,7 +186,7 @@ void Renderer::SwapBuffers(void)
int width = rcWindow.right - rcWindow.left;
int height = rcWindow.bottom - rcWindow.top;
::MoveWindow(EmuWindow::GetWnd(), 0,0,width,height, FALSE);
::MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
// nBackbufferWidth = width;
// nBackbufferHeight = height;
}
@ -230,11 +224,11 @@ void Renderer::SwapBuffers(void)
ProcessMessages();
#if defined(DVPROFILE)
if( g_bWriteProfile ) {
if (g_bWriteProfile) {
//g_bWriteProfile = 0;
static int framenum = 0;
const int UPDATE_FRAMES = 8;
if( ++framenum >= UPDATE_FRAMES ) {
if (++framenum >= UPDATE_FRAMES) {
DVProfWrite("prof.txt", UPDATE_FRAMES);
DVProfClear();
framenum = 0;
@ -248,10 +242,9 @@ void Renderer::SwapBuffers(void)
//clean out old stuff from caches
frameCount++;
PShaderCache::Cleanup();
VShaderCache::Cleanup();
PixelShaderCache::Cleanup();
VertexShaderCache::Cleanup();
TextureCache::Cleanup();
//DListCache::Cleanup();
//////////////////////////////////////////////////////////////////////////
//Begin new frame
@ -272,7 +265,8 @@ void Renderer::SwapBuffers(void)
rc.bottom = (LONG)m_height;
D3D::dev->SetScissorRect(&rc);
u32 clearColor = (bpmem.clearcolorAR<<16)|bpmem.clearcolorGB;
D3D::dev->Clear(0, 0, D3DCLEAR_TARGET, 0x101010, 0, 0);
u32 clearColor = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
// clearColor |= 0x003F003F;
// D3D::BeginFrame(true,clearColor,1.0f);
D3D::BeginFrame(false, clearColor, 1.0f);
@ -285,6 +279,7 @@ void Renderer::SwapBuffers(void)
D3D::font.SetRenderStates(); //compatibility with low end cards
}
/*
void Renderer::SetViewport(float* _Viewport)
{
Viewport* pViewport = (Viewport*)_Viewport;
@ -300,13 +295,13 @@ void Renderer::SetViewport(float* _Viewport)
if (y < 0.0f) y = 0.0f;
if (x > 640.0f) x = 639.0f;
if (y > 480.0f) y = 479.0f;
if (w < 0) w=1;
if (h < 0) h=1;
if (w < 0) w = 0;
if (h < 0) h = 0;
if (x+w > 640.0f) w=640-x;
if (y+h > 480.0f) h=480-y;
//x=y=0;
//if(w>0.0f) w=0.0f;
//if(h<0.0f) h=0.0f;
//if (w>0.0f) w=0.0f;
//if (h<0.0f) h=0.0f;
vp.X = (DWORD)(x*xScale);
vp.Y = (DWORD)(y*yScale);
@ -321,9 +316,12 @@ void Renderer::SetViewport(float* _Viewport)
D3D::dev->SetViewport(&vp);
}
*/
void Renderer::SetScissorBox(RECT &rc)
void Renderer::SetScissorRect()
{
RECT rc = {0,0,0,0}; // FIXX
rc.left = (int)(rc.left * xScale);
rc.top = (int)(rc.top * yScale);
rc.right = (int)(rc.right * xScale);
@ -334,6 +332,7 @@ void Renderer::SetScissorBox(RECT &rc)
g_VideoInitialize.pLog("SCISSOR ERROR", FALSE);
}
/*
void Renderer::SetProjection(float* pMatrix, int constantIndex)
{
D3DXMATRIX mtx;
@ -349,10 +348,17 @@ void Renderer::SetProjection(float* pMatrix, int constantIndex)
mtx.m[1][2] = pMatrix[3];
mtx.m[1][3] = 0; // +0.5f/m_height; <-- fix d3d pixel center?
<<<<<<< .mine
mtx.m[0][2] = 0.0f;
mtx.m[1][2] = 0.0f;
mtx.m[2][2] = -(1 - pMatrix[4]);
mtx.m[3][2] = pMatrix[5];
=======
mtx.m[2][0] = 0.0f;
mtx.m[2][1] = 0.0f;
mtx.m[2][2] = -(1.0f - pMatrix[4]);
mtx.m[2][3] = pMatrix[5]; // Problematic in OGL
>>>>>>> .r2480
mtx.m[3][0] = 0.0f;
mtx.m[3][1] = 0.0f;
@ -384,54 +390,97 @@ void Renderer::SetProjection(float* pMatrix, int constantIndex)
mtx.m[3][3] = 1.0f;
}
D3D::dev->SetVertexShaderConstantF(constantIndex, mtx, 4);
}
}*/
void Renderer::SetTexture( DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture )
void Renderer::SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture)
{
if ( m_Textures[Stage] != pTexture )
if (m_Textures[Stage] != pTexture)
{
m_Textures[Stage] = pTexture;
D3D::dev->SetTexture( Stage, pTexture );
D3D::dev->SetTexture(Stage, pTexture);
}
}
void Renderer::SetFVF( DWORD FVF )
void Renderer::SetFVF(DWORD FVF)
{
if ( m_FVF != FVF )
if (m_FVF != FVF)
{
m_FVF = FVF;
D3D::dev->SetFVF( FVF );
D3D::dev->SetFVF(FVF);
}
}
void Renderer::SetRenderState( D3DRENDERSTATETYPE State, DWORD Value )
void Renderer::SetRenderState(D3DRENDERSTATETYPE State, DWORD Value)
{
if ( m_RenderStates[State] != Value )
if (m_RenderStates[State] != Value)
{
m_RenderStates[State] = Value;
D3D::dev->SetRenderState( State, Value );
D3D::dev->SetRenderState(State, Value);
}
}
void Renderer::SetTextureStageState( DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value )
void Renderer::SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value)
{
if ( m_TextureStageStates[Stage][Type] != Value )
if (m_TextureStageStates[Stage][Type] != Value)
{
m_TextureStageStates[Stage][Type] = Value;
D3D::dev->SetTextureStageState( Stage, Type, Value );
D3D::dev->SetTextureStageState(Stage, Type, Value);
}
}
void Renderer::SetSamplerState( DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value )
void Renderer::SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value)
{
if ( m_SamplerStates[Sampler][Type] != Value )
if (m_SamplerStates[Sampler][Type] != Value)
{
m_SamplerStates[Sampler][Type] = Value;
D3D::dev->SetSamplerState( Sampler, Type, Value );
D3D::dev->SetSamplerState(Sampler, Type, Value);
}
}
// Called from VertexShaderManager
void UpdateViewport()
{
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
// [0] = width/2
// [1] = height/2
// [2] = 16777215 *(farz - nearz)
// [3] = xorig + width/2 + 342
// [4] = yorig + height/2 + 342
// [5] = 16777215 * farz
/*INFO_LOG("view: topleft=(%f,%f), wh=(%f,%f), z=(%f,%f)\n",
rawViewport[3]-rawViewport[0]-342, rawViewport[4]+rawViewport[1]-342,
2 * rawViewport[0], 2 * rawViewport[1],
(rawViewport[5] - rawViewport[2]) / 16777215.0f, rawViewport[5] / 16777215.0f);*/
D3DVIEWPORT9 vp;
// Keep aspect ratio at 4:3
// rawViewport[0] = 320, rawViewport[1] = -240
int scissorXOff = bpmem.scissorOffset.x * 2 - 342;
int scissorYOff = bpmem.scissorOffset.y * 2 - 342;
float fourThree = 4.0f / 3.0f;
float wAdj, hAdj;
float actualRatiow, actualRatioh;
int overfl;
int xoffs = 0;
int yoffs = 0;
int wid, hei, actualWid, actualHei;
int winw = 640;
int winh = 480;
float ratio = (float)winw / (float)winh / fourThree;
vp.MinZ = (xfregs.rawViewport[5] - xfregs.rawViewport[2])/16777215.0f;
vp.MaxZ = xfregs.rawViewport[5]/16777215.0f;
wid = ceil(fabs(2 * xfregs.rawViewport[0]));
hei = ceil(fabs(2 * xfregs.rawViewport[1]));
vp.X = (int)(xfregs.rawViewport[3] - xfregs.rawViewport[0] - 342 - scissorXOff) + xoffs;
vp.Y = (int)(xfregs.rawViewport[4] - xfregs.rawViewport[1] - 342 - scissorYOff) + yoffs;
vp.Width = wid;
vp.Height = hei;
D3D::dev->SetViewport(&vp);
}

View File

@ -48,19 +48,19 @@ public:
static void Init(SVideoInitialize &_VideoInitialize);
static void Shutdown();
static void Initialize(void);
static void Initialize();
// must be called if the window size has changed
static void ReinitView(void);
static void ReinitView();
static void SwapBuffers(void);
static void SwapBuffers();
static float GetXScale() {return xScale;}
static float GetYScale() {return yScale;}
static float GetXScale() { return xScale; }
static float GetYScale() { return yScale; }
static void SetScissorBox(RECT &rc);
static void SetViewport(float* _Viewport);
static void SetProjection(float* _pProjection, int constantIndex = -1);
static void SetScissorRect();
// static void SetViewport(float* _Viewport);
// static void SetProjection(float* _pProjection, int constantIndex = -1);
// The little status display.
static void AddMessage(const std::string &message, unsigned int ms);
@ -68,11 +68,11 @@ public:
static void RenderText(const std::string &text, int left, int top, unsigned int color);
// The following are "filtered" versions of the corresponding D3Ddev-> functions.
static void SetTexture( DWORD Stage, IDirect3DBaseTexture9 *pTexture );
static void SetFVF( DWORD FVF );
static void SetRenderState( D3DRENDERSTATETYPE State, DWORD Value );
static void SetTextureStageState( DWORD Stage, D3DTEXTURESTAGESTATETYPE Type,DWORD Value );
static void SetSamplerState( DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value );
static void SetTexture(DWORD Stage, IDirect3DBaseTexture9 *pTexture);
static void SetFVF(DWORD FVF);
static void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value);
static void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
static void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
};
#endif // __H_RENDER__

View File

@ -1,372 +0,0 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include <fvec.h>
#include "Common.h"
#include "Profiler.h"
// #include "Globals.h"
#include "Vec3.h"
#include "TransformEngine.h"
#include "VertexManager.h"
#include "VertexLoader.h"
#include "BPStructs.h"
#include "XFStructs.h"
#include "Utils.h"
#include "RGBAFloat.h"
float *CTransformEngine::m_pPosMatrix;
float *CTransformEngine::m_pNormalMatrix;
float *CTransformEngine::m_pTexMatrix[8];
float *CTransformEngine::m_pTexPostMatrix[8];
const Light *GetLight(int i)
{
return (const Light *)(xfmem + XFMEM_LIGHTS) + i;
}
float DoLighting(const Light *light, const LitChannel &chan, const Vec3 &pos, const Vec3 &normal)
{
float val;
if (chan.attnfunc == 0 || chan.attnfunc == 2) //no attn
{
Vec3 ldir = (Vec3(light->dpos) - pos);
val = ldir.normalized() * normal;
}
else
{
float aattn = 0;
float d;
float mul = 1.0f;
if (chan.attnfunc == 3)
{
Vec3 ldir = (Vec3(light->dpos) - pos);
d = ldir.length();
Vec3 ldirNorm = ldir / d; //normalize
float l = ldirNorm * normal;
aattn = Vec3(light->ddir) * ldirNorm;
mul = l;
}
else if (chan.attnfunc == 1)
{
d = aattn = Vec3(light->shalfangle) * normal;
mul = (Vec3(light->sdir) * normal > 0) ? (normal * Vec3(light->shalfangle)) : 0;
if (mul < 0)
mul = 0;
}
float spot = (light->a2*aattn*aattn + light->a1*aattn + light->a0);
float dist = 1.0f/(light->k2*d*d + light->k1*d + light->k0);
if (spot<0)
spot=0;
val = mul * spot * dist;
}
if (val < 0 && chan.diffusefunc == 2) // clamp
val = 0;
return val;
}
void VtxMulMtx43T(Vec3 &out, const Vec3 &in, const float pMatrix[12])
{
out.x = in.x * pMatrix[0] + in.y * pMatrix[1] + in.z * pMatrix[2] + 1 * pMatrix[3];
out.y = in.x * pMatrix[4] + in.y * pMatrix[5] + in.z * pMatrix[6] + 1 * pMatrix[7];
out.z = in.x * pMatrix[8] + in.y * pMatrix[9] + in.z * pMatrix[10] + 1 * pMatrix[11];
}
void VtxMulMtx43(Vec3 &out, const Vec3 &in, const float pMatrix[12])
{
VtxMulMtx43T(out,in,pMatrix);
//TODO(XK): Turns out that SSE2 computations are slower... Can anyone do
// anything about it?
/*
F32vec4 a(in.x, in.y, in.z, 1), b(pMatrix[0], pMatrix[1], pMatrix[2], pMatrix[3]);
out.x = add_horizontal(a * b);
b[0] = pMatrix[4]; b[1] = pMatrix[5]; b[2] = pMatrix[6]; b[3] = pMatrix[7];
out.y = add_horizontal(a * b);
b[0] = pMatrix[8]; b[1] = pMatrix[9]; b[2] = pMatrix[10]; b[3] = pMatrix[11];
out.z = add_horizontal(a * b);
*/
}
void VtxMulMtx42(Vec3 &out, const Vec3 &in, const float pMatrix[8])
{
out.x = in.x * pMatrix[0] + in.y * pMatrix[1] + in.z * pMatrix[2] + 1 * pMatrix[3];
out.y = in.x * pMatrix[4] + in.y * pMatrix[5] + in.z * pMatrix[6] + 1 * pMatrix[7];
}
void VtxMulMtx33(Vec3 &out, const Vec3 &in, const float pMatrix[9])
{
out.x = in.x * pMatrix[0] + in.y * pMatrix[1] + in.z * pMatrix[2];
out.y = in.x * pMatrix[3] + in.y * pMatrix[4] + in.z * pMatrix[5];
out.z = in.x * pMatrix[6] + in.y * pMatrix[7] + in.z * pMatrix[8];
}
void CTransformEngine::TransformVertices(int _numVertices, const DecodedVArray *varray, D3DVertex *vbuffer)
{
if (vbuffer == 0)
{
MessageBox(0,"TransformVertices : vbuffer == 0","WTF",0);
}
DVSTARTPROFILE();
RGBAFloat lightColors[8];
RGBAFloat lightVals[8];
RGBAFloat chans[2];
u32 components = varray->GetComponents();
// TODO: only for active lights
for (int i=0; i<8; i++)
lightColors[i].convert_GC(GetLight(i)->color);
for (int i=0; i<_numVertices; i++)
{
//////////////////////////////////////////////////////////////////////////
//Step 1: xform position and normal
//////////////////////////////////////////////////////////////////////////
Vec3 OrigPos = varray->GetPos(i);
if (varray->hasPosMatIdx)
{
int index = varray->GetPosMtxInd(i);
SetPosNormalMatrix(
(float*)xfmem + (index & 63) * 4, //CHECK
(float*)xfmem + 0x400 + 3 * (index & 31)); //CHECK
}
for (int j = 0; j < 8; j++)
{
if (varray->hasTexMatIdx[j])
{
float *flipmem = (float *)xfmem;
int index = varray->GetTexMtxInd(j, i);
SetTexMatrix(j, flipmem + index * 4);
}
}
Vec3 TempPos;
// m_pPosMatrix can be switched out, through matrixindex vertex components
VtxMulMtx43(TempPos, OrigPos, m_pPosMatrix);
Vec3 TempNormal;
Vec3 OrigNormal;
if (varray->hasNrm)
{
OrigNormal = varray->GetNormal(0, i);
VtxMulMtx33(TempNormal, OrigNormal, m_pNormalMatrix);
TempNormal.normalize();
}
else
{
OrigNormal.setZero();
TempNormal.setZero();
}
//////////////////////////////////////////////////////////////////////////
//Step 2: Light!
//////////////////////////////////////////////////////////////////////////
//find all used lights
u32 lightMask =
xfregs.colChans[0].color.GetFullLightMask() | xfregs.colChans[0].alpha.GetFullLightMask() |
xfregs.colChans[1].color.GetFullLightMask() | xfregs.colChans[1].alpha.GetFullLightMask();
float r0=0,g0=0,b0=0,a0=0;
//go through them and compute the lit colors
//Sum lighting for both two color channels if they're active
for (int j = 0; j < (int)bpmem.genMode.numcolchans; j++)
{
RGBAFloat material;
RGBAFloat lightSum(0,0,0,0);
bool hasColorJ = (components & (VertexLoader::VB_HAS_COL0 << j)) != 0;
//get basic material color from appropriate sources (this would compile nicely!:)
if (xfregs.colChans[j].color.matsource == GX_SRC_REG)
material.convertRGB_GC(xfregs.colChans[j].matColor);
else
{
if (hasColorJ)
material.convertRGB(varray->GetColor(j, i));
else
material.r=material.g=material.b=1.0f;
}
if (xfregs.colChans[j].alpha.matsource == GX_SRC_REG)
material.convertA_GC(xfregs.colChans[j].matColor);
else
{
if (hasColorJ)
material.convertA(varray->GetColor(j, i));
else
material.a=1.0f;
}
//combine together the light values from the lights that affect the color
if (xfregs.colChans[j].color.enablelighting)
{
//choose ambient source and start our lightsum accumulator with its value..
if (xfregs.colChans[j].color.ambsource == GX_SRC_REG)
lightSum.convertRGB_GC(xfregs.colChans[j].ambColor); //ambient
else
{
if (hasColorJ)
lightSum.convertRGB(varray->GetColor(j, i));
else
{
lightSum.r=0.0f;lightSum.g=0.0f;lightSum.b=0.0f;
}
}
//accumulate light colors
int cmask = xfregs.colChans[j].color.GetFullLightMask();
for (int l=0; l<8; l++)
{
if (cmask&1)
{
float val = DoLighting(GetLight(l), xfregs.colChans[j].color, TempPos, TempNormal);
float r = lightColors[l].r * val;
float g = lightColors[l].g * val;
float b = lightColors[l].b * val;
lightSum.r += r;
lightSum.g += g;
lightSum.b += b;
}
cmask >>= 1;
}
}
else
{
lightSum.r = lightSum.g = lightSum.b = 1.0f;
}
//combine together the light values from the lights that affect alpha (should be rare)
if (xfregs.colChans[j].alpha.enablelighting)
{
//choose ambient source..
if (xfregs.colChans[j].alpha.ambsource==GX_SRC_REG)
lightSum.convertA_GC(xfregs.colChans[j].ambColor);
else
{
if (hasColorJ)
lightSum.convertA(varray->GetColor(j, i));
else
lightSum.a=0.0f;
}
//accumulate light alphas
int amask = xfregs.colChans[j].alpha.GetFullLightMask();
for (int l = 0; l < 8; l++)
{
if (amask&1)
{
float val = DoLighting(GetLight(l), xfregs.colChans[j].alpha, TempPos, TempNormal);
float a = lightColors[l].a * val;
lightSum.a += a;
}
amask >>= 1;
}
}
else
{
lightSum.a=1.0f;
}
chans[j] = lightSum * material;
chans[j].clamp();
}
//////////////////////////////////////////////////////////////////////////
//Step 3: Generate texture coordinates!
//////////////////////////////////////////////////////////////////////////
Vec3 TempUVs[8];
for (int j = 0; j < xfregs.numTexGens; j++)
{
Vec3 t;
switch (xfregs.texcoords[j].texmtxinfo.sourcerow) {
case XF_SRCGEOM_INROW: t = OrigPos; break; //HACK WTFF???
case XF_SRCNORMAL_INROW: t = OrigNormal; break;
case XF_SRCCOLORS_INROW: break; //set uvs to something?
case XF_SRCBINORMAL_T_INROW: t=Vec3(0,0,0);break;
case XF_SRCBINORMAL_B_INROW: t=Vec3(0,0,0);break;
default:
{
int c = xfregs.texcoords[j].texmtxinfo.sourcerow - XF_SRCTEX0_INROW;
bool hasTCC = (components & (VertexLoader::VB_HAS_UV0 << c)) != 0;
if (c >= 0 && c <= 7 && hasTCC)
{
const DecUV &uv = varray->GetUV(c, i);
t = Vec3(uv.u, uv.v, 1);
}
}
}
Vec3 out,out2;
switch (xfregs.texcoords[j].texmtxinfo.texgentype)
{
case XF_TEXGEN_COLOR_STRGBC0:
out = Vec3(chans[0].r*255, chans[0].g*255, 1)/255.0f;
break;
case XF_TEXGEN_COLOR_STRGBC1:
out = Vec3(chans[1].r*255, chans[1].g*255, 1)/255.0f; //FIX: take color1 instead
break;
case XF_TEXGEN_REGULAR:
if (xfregs.texcoords[j].texmtxinfo.projection)
VtxMulMtx43(out, t, m_pTexMatrix[j]);
else
VtxMulMtx42(out, t, m_pTexMatrix[j]);
break;
}
if (xfregs.texcoords[j].postmtxinfo.normalize)
out.normalize();
int postMatrix = xfregs.texcoords[j].postmtxinfo.index;
float *pmtx = ((float*)xfmem) + 0x500 + postMatrix * 4; //CHECK
//multiply with postmatrix
VtxMulMtx43(TempUVs[j], out, pmtx);
}
//////////////////////////////////////////////////////////////////////////
//Step 4: Output the vertex!
//////////////////////////////////////////////////////////////////////////
for (int j = 0; j < 2; j++)
chans[j].convertToD3DColor(vbuffer[i].colors[j]);
vbuffer[i].pos = TempPos;
vbuffer[i].normal = TempNormal;
for (int j = 0; j < (int)bpmem.genMode.numtexgens; j++)
{
vbuffer[i].uv[j].u = TempUVs[j].x;
vbuffer[i].uv[j].v = TempUVs[j].y;
vbuffer[i].uv[j].w = TempUVs[j].z;
}
}
}

View File

@ -1,55 +0,0 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _TRANSFORMENGINE_H
#define _TRANSFORMENGINE_H
//T&L Engine
//as much work as possible will be delegated to vertex shaders later
//to take full advantage of current PC HW
#include "VertexManager.h"
#include "DecodedVArray.h"
class CTransformEngine
{
static float* m_pPosMatrix;
static float* m_pNormalMatrix;
static float* m_pTexMatrix[8];
static float* m_pTexPostMatrix[8];
public:
static void TransformVertices(int _numVertices,
const DecodedVArray *varray,
D3DVertex *vbuffer);
static void SetPosNormalMatrix(float *p, float *n)
{
m_pPosMatrix = p;
m_pNormalMatrix = n;
}
static void SetTexMatrix(int i, float *f)
{
m_pTexMatrix[i] = f;
}
static void SetTexPostMatrix(int i, float *f)
{
m_pTexPostMatrix[i] = f;
}
};
#endif

View File

@ -1,363 +0,0 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include <stdio.h>
#include "x64Emitter.h"
#include "Common.h"
#include "LookUpTables.h"
#include "Profiler.h"
#include "VertexManager.h"
#include "VertexLoader.h"
#include "XFStructs.h"
#include "BPStructs.h"
#include "DataReader.h"
#include "DecodedVArray.h"
//these don't need to be saved
float posScale;
float tcScale[8];
int tcElements[8];
int tcFormat[8];
int colElements[2];
float tcScaleU[8];
float tcScaleV[8];
int tcIndex;
int colIndex;
u32 addr;
DecodedVArray *varray;
int ComputeVertexSize(u32 comp)
{
int size = 0;
if (comp & VertexLoader::VB_HAS_POSMTXIDX)
size += 4;
if (comp & (VertexLoader::VB_HAS_TEXMTXIDX0 | VertexLoader::VB_HAS_TEXMTXIDX1 | VertexLoader::VB_HAS_TEXMTXIDX2 | VertexLoader::VB_HAS_TEXMTXIDX3))
size += 4;
if (comp & (VertexLoader::VB_HAS_TEXMTXIDX4 | VertexLoader::VB_HAS_TEXMTXIDX5 | VertexLoader::VB_HAS_TEXMTXIDX6 | VertexLoader::VB_HAS_TEXMTXIDX7))
size += 4;
if (comp & VertexLoader::VB_HAS_NRM0)
size += 4;
if (comp & (VertexLoader::VB_HAS_NRM1 | VertexLoader::VB_HAS_NRM2)) //combine into single check for speed
size += 8;
if (comp & VertexLoader::VB_HAS_COL0)
size += 4;
if (comp & VertexLoader::VB_HAS_COL1)
size += 4;
for (int i = 0; i < 8; i++)
if (comp & (VertexLoader::VB_HAS_UV0 << i))
size += 8;
return size;
}
void VertexLoader::SetVArray(DecodedVArray *_varray)
{
varray = _varray;
}
#include "VertexLoader_MtxIndex.h"
#include "VertexLoader_Position.h"
#include "VertexLoader_Normal.h"
#include "VertexLoader_Color.h"
#include "VertexLoader_TextCoord.h"
VertexLoader g_VertexLoaders[8];
TVtxDesc VertexLoader::m_VtxDesc;
bool VertexLoader::m_DescDirty = true;
VertexLoader::VertexLoader()
{
m_numPipelineStates = 0;
m_VertexSize = 0;
m_AttrDirty = true;
VertexLoader_Normal::Init();
}
VertexLoader::~VertexLoader()
{
}
void VertexLoader::Setup()
{
if (!m_AttrDirty && !m_DescDirty)
return;
DVSTARTPROFILE();
// Reset pipeline
m_VertexSize = 0;
m_numPipelineStates = 0;
m_components = 0;
// Position Matrix Index
if (m_VtxDesc.PosMatIdx)
{
m_PipelineStates[m_numPipelineStates++] = PosMtx_ReadDirect_UByte;
m_VertexSize += 1;
m_components |= VB_HAS_POSMTXIDX;
}
// Texture matrix indices
if (m_VtxDesc.Tex0MatIdx) {m_components|=VB_HAS_TEXMTXIDX0; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;}
if (m_VtxDesc.Tex1MatIdx) {m_components|=VB_HAS_TEXMTXIDX1; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;}
if (m_VtxDesc.Tex2MatIdx) {m_components|=VB_HAS_TEXMTXIDX2; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;}
if (m_VtxDesc.Tex3MatIdx) {m_components|=VB_HAS_TEXMTXIDX3; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;}
if (m_VtxDesc.Tex4MatIdx) {m_components|=VB_HAS_TEXMTXIDX4; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;}
if (m_VtxDesc.Tex5MatIdx) {m_components|=VB_HAS_TEXMTXIDX5; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;}
if (m_VtxDesc.Tex6MatIdx) {m_components|=VB_HAS_TEXMTXIDX6; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;}
if (m_VtxDesc.Tex7MatIdx) {m_components|=VB_HAS_TEXMTXIDX7; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;}
// Position
switch (m_VtxDesc.Position)
{
case NOT_PRESENT: {_assert_msg_(0,"Vertex descriptor without position!","WTF?");} break;
case DIRECT:
{
int SizePro = 0;
switch (m_VtxAttr.PosFormat)
{
case FORMAT_UBYTE: SizePro=1; WriteCall(Pos_ReadDirect_UByte); break;
case FORMAT_BYTE: SizePro=1; WriteCall(Pos_ReadDirect_Byte); break;
case FORMAT_USHORT: SizePro=2; WriteCall(Pos_ReadDirect_UShort); break;
case FORMAT_SHORT: SizePro=2; WriteCall(Pos_ReadDirect_Short); break;
case FORMAT_FLOAT: SizePro=4; WriteCall(Pos_ReadDirect_Float); break;
default: _assert_(0); break;
}
if (m_VtxAttr.PosElements == 1)
m_VertexSize += SizePro * 3;
else
m_VertexSize += SizePro * 2;
}
break;
case INDEX8:
m_VertexSize+=1;
switch (m_VtxAttr.PosFormat)
{
case FORMAT_UBYTE: WriteCall(Pos_ReadIndex8_UByte); break; //WTF?
case FORMAT_BYTE: WriteCall(Pos_ReadIndex8_Byte); break;
case FORMAT_USHORT: WriteCall(Pos_ReadIndex8_UShort); break;
case FORMAT_SHORT: WriteCall(Pos_ReadIndex8_Short); break;
case FORMAT_FLOAT: WriteCall(Pos_ReadIndex8_Float); break;
default: _assert_(0); break;
}
break;
case INDEX16:
m_VertexSize+=2;
switch (m_VtxAttr.PosFormat)
{
case FORMAT_UBYTE: WriteCall(Pos_ReadIndex16_UByte); break;
case FORMAT_BYTE: WriteCall(Pos_ReadIndex16_Byte); break;
case FORMAT_USHORT: WriteCall(Pos_ReadIndex16_UShort); break;
case FORMAT_SHORT: WriteCall(Pos_ReadIndex16_Short); break;
case FORMAT_FLOAT: WriteCall(Pos_ReadIndex16_Float); break;
default: _assert_(0); break;
}
break;
}
// Normals
if (m_VtxDesc.Normal != NOT_PRESENT)
{
VertexLoader_Normal::index3 = m_VtxAttr.NormalIndex3 ? true : false;
unsigned int uSize = VertexLoader_Normal::GetSize(m_VtxDesc.Normal, m_VtxAttr.NormalFormat, m_VtxAttr.NormalElements);
TPipelineFunction pFunc = VertexLoader_Normal::GetFunction(m_VtxDesc.Normal, m_VtxAttr.NormalFormat, m_VtxAttr.NormalElements);
if (pFunc == 0)
{
char temp[256];
sprintf(temp,"%i %i %i", m_VtxDesc.Normal, m_VtxAttr.NormalFormat, m_VtxAttr.NormalElements);
MessageBox(0,"VertexLoader_Normal::GetFunction returned zero!",temp,0);
}
WriteCall(pFunc);
m_VertexSize += uSize;
int m_numNormals = (m_VtxAttr.NormalElements == 1) ? NRM_THREE : NRM_ONE;
m_components |= VB_HAS_NRM0;
if (m_numNormals == NRM_THREE)
m_components |= VB_HAS_NRM1 | VB_HAS_NRM2;
}
// Colors
int col[2] = {m_VtxDesc.Color0, m_VtxDesc.Color1};
for (int i = 0; i < 2; i++)
SetupColor(i,col[i], m_VtxAttr.color[i].Comp, m_VtxAttr.color[i].Elements);
// TextureCoord
// Since m_VtxDesc.Text7Coord is broken across a 32 bit word boundary, retrieve its value manually.
// If we didn't do this, the vertex format would be read as one bit offset from where it should be, making
// 01 become 00, and 10/11 become 01
int tc[8] = {
m_VtxDesc.Tex0Coord, m_VtxDesc.Tex1Coord, m_VtxDesc.Tex2Coord, m_VtxDesc.Tex3Coord,
m_VtxDesc.Tex4Coord, m_VtxDesc.Tex5Coord, m_VtxDesc.Tex6Coord, (m_VtxDesc.Hex >> 31) & 3
};
for (int i = 0; i < 8; i++)
SetupTexCoord(i, tc[i],
m_VtxAttr.texCoord[i].Format,
m_VtxAttr.texCoord[i].Elements,
m_VtxAttr.texCoord[i].Frac);
}
void VertexLoader::SetupColor(int num, int mode, int format, int elements)
{
m_components |= VB_HAS_COL0 << num;
switch (mode)
{
case NOT_PRESENT:
m_components &= ~(VB_HAS_COL0 << num);
break;
case DIRECT:
switch (format)
{
case FORMAT_16B_565: m_VertexSize+=2; WriteCall(Color_ReadDirect_16b_565); break;
case FORMAT_24B_888: m_VertexSize+=3; WriteCall(Color_ReadDirect_24b_888); break;
case FORMAT_32B_888x: m_VertexSize+=4; WriteCall(Color_ReadDirect_32b_888x); break;
case FORMAT_16B_4444: m_VertexSize+=2; WriteCall(Color_ReadDirect_16b_4444); break;
case FORMAT_24B_6666: m_VertexSize+=3; WriteCall(Color_ReadDirect_24b_6666); break;
case FORMAT_32B_8888: m_VertexSize+=4; WriteCall(Color_ReadDirect_32b_8888); break;
default: _assert_(0); break;
}
break;
case INDEX8:
switch (format)
{
case FORMAT_16B_565: WriteCall(Color_ReadIndex8_16b_565); break;
case FORMAT_24B_888: WriteCall(Color_ReadIndex8_24b_888); break;
case FORMAT_32B_888x: WriteCall(Color_ReadIndex8_32b_888x); break;
case FORMAT_16B_4444: WriteCall(Color_ReadIndex8_16b_4444); break;
case FORMAT_24B_6666: WriteCall(Color_ReadIndex8_24b_6666); break;
case FORMAT_32B_8888: WriteCall(Color_ReadIndex8_32b_8888); break;
default: _assert_(0); break;
}
m_VertexSize+=1;
break;
case INDEX16:
switch (format)
{
case FORMAT_16B_565: WriteCall(Color_ReadIndex16_16b_565); break;
case FORMAT_24B_888: WriteCall(Color_ReadIndex16_24b_888); break;
case FORMAT_32B_888x: WriteCall(Color_ReadIndex16_32b_888x); break;
case FORMAT_16B_4444: WriteCall(Color_ReadIndex16_16b_4444); break;
case FORMAT_24B_6666: WriteCall(Color_ReadIndex16_24b_6666); break;
case FORMAT_32B_8888: WriteCall(Color_ReadIndex16_32b_8888); break;
default: _assert_(0); break;
}
m_VertexSize+=2;
break;
}
}
void VertexLoader::SetupTexCoord(int num, int mode, int format, int elements, int _iFrac)
{
m_components |= VB_HAS_UV0 << num;
switch (mode)
{
case NOT_PRESENT:
m_components &= ~(VB_HAS_UV0 << num);
break;
case DIRECT:
{
int sizePro=0;
switch (format)
{
case FORMAT_UBYTE: sizePro = 1; WriteCall(TexCoord_ReadDirect_UByte); break;
case FORMAT_BYTE: sizePro = 1; WriteCall(TexCoord_ReadDirect_Byte); break;
case FORMAT_USHORT: sizePro = 2; WriteCall(TexCoord_ReadDirect_UShort); break;
case FORMAT_SHORT: sizePro = 2; WriteCall(TexCoord_ReadDirect_Short); break;
case FORMAT_FLOAT: sizePro = 4; WriteCall(TexCoord_ReadDirect_Float); break;
default: _assert_(0); break;
}
m_VertexSize += sizePro * (elements ? 2 : 1);
}
break;
case INDEX8:
switch (format)
{
case FORMAT_UBYTE: WriteCall(TexCoord_ReadIndex8_UByte); break;
case FORMAT_BYTE: WriteCall(TexCoord_ReadIndex8_Byte); break;
case FORMAT_USHORT: WriteCall(TexCoord_ReadIndex8_UShort); break;
case FORMAT_SHORT: WriteCall(TexCoord_ReadIndex8_Short); break;
case FORMAT_FLOAT: WriteCall(TexCoord_ReadIndex8_Float); break;
default: _assert_(0); break;
}
m_VertexSize+=1;
break;
case INDEX16:
switch (format)
{
case FORMAT_UBYTE: WriteCall(TexCoord_ReadIndex16_UByte); break;
case FORMAT_BYTE: WriteCall(TexCoord_ReadIndex16_Byte); break;
case FORMAT_USHORT: WriteCall(TexCoord_ReadIndex16_UShort); break;
case FORMAT_SHORT: WriteCall(TexCoord_ReadIndex16_Short); break;
case FORMAT_FLOAT: WriteCall(TexCoord_ReadIndex16_Float); break;
default: _assert_(0);
}
m_VertexSize+=2;
break;
}
}
void VertexLoader::WriteCall(TPipelineFunction func)
{
m_PipelineStates[m_numPipelineStates++] = func;
}
using namespace Gen;
void VertexLoader::PrepareRun()
{
posScale = shiftLookup[m_VtxAttr.PosFrac];
for (int i = 0; i < 8; i++)
{
tcScaleU[i] = shiftLookup[m_VtxAttr.texCoord[i].Frac];
tcScaleV[i] = shiftLookup[m_VtxAttr.texCoord[i].Frac];
tcElements[i] = m_VtxAttr.texCoord[i].Elements;
tcFormat[i] = m_VtxAttr.texCoord[i].Format;
}
for (int i = 0; i < 2; i++)
colElements[i] = m_VtxAttr.color[i].Elements;
varray->SetComponents(m_components);
}
void VertexLoader::RunVertices(int count)
{
DVSTARTPROFILE();
for (int v = 0; v < count; v++)
{
tcIndex = 0;
colIndex = 0;
s_texmtxread = 0;
for (int i = 0; i < m_numPipelineStates; i++)
{
m_PipelineStates[i](&m_VtxAttr);
}
varray->Next();
}
/*
This is not the bottleneck ATM, so compiling etc doesn't really help.
At least not when all we do is compile it to a list of function calls.
Should help more when we inline, but this requires the new vertex format.
Maybe later, and with smarter caching.
if (count)
{
this->m_counter = count;
((void (*)())((void*)&m_compiledCode[0]))();
}*/
}

View File

@ -1,194 +0,0 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _VERTEXLOADER_H
#define _VERTEXLOADER_H
int ComputeVertexSize(u32 components);
#include "CPStructs.h"
#include "DecodedVArray.h"
#include "DataReader.h"
#define LOADERDECL __cdecl
typedef void (LOADERDECL *TPipelineFunction)(const void*);
class VertexLoader
{
public:
enum
{
NRM_ZERO = 0,
NRM_ONE = 1,
NRM_THREE = 3
};
enum {
VB_HAS_POSMTXIDX =(1<<1),
VB_HAS_TEXMTXIDX0=(1<<2),
VB_HAS_TEXMTXIDX1=(1<<3),
VB_HAS_TEXMTXIDX2=(1<<4),
VB_HAS_TEXMTXIDX3=(1<<5),
VB_HAS_TEXMTXIDX4=(1<<6),
VB_HAS_TEXMTXIDX5=(1<<7),
VB_HAS_TEXMTXIDX6=(1<<8),
VB_HAS_TEXMTXIDX7=(1<<9),
VB_HAS_TEXMTXIDXALL=(0xff<<2),
//VB_HAS_POS=0, // Implied, it always has pos! don't bother testing
VB_HAS_NRM0=(1<<10),
VB_HAS_NRM1=(1<<11),
VB_HAS_NRM2=(1<<12),
VB_HAS_NRMALL=(7<<10),
VB_HAS_COL0=(1<<13),
VB_HAS_COL1=(1<<14),
VB_HAS_UV0=(1<<15),
VB_HAS_UV1=(1<<16),
VB_HAS_UV2=(1<<17),
VB_HAS_UV3=(1<<18),
VB_HAS_UV4=(1<<19),
VB_HAS_UV5=(1<<20),
VB_HAS_UV6=(1<<21),
VB_HAS_UV7=(1<<22),
VB_HAS_UVALL=(0xff<<15),
VB_HAS_UVTEXMTXSHIFT=13,
};
private:
TPipelineFunction m_PipelineStates[32];
int m_numPipelineStates;
int m_VertexSize;
int m_counter;
u32 m_components;
UVAT_group0 m_group0;
UVAT_group1 m_group1;
UVAT_group2 m_group2;
bool m_AttrDirty;
TVtxAttr m_VtxAttr; //Decoded into easy format
//common for all loaders
static TVtxDesc m_VtxDesc;
static bool m_DescDirty;
// seup the pipeline with this vertex fmt
void SetupColor(int num, int _iMode, int _iFormat, int _iElements);
void SetupTexCoord(int num, int _iMode, int _iFormat, int _iElements, int _iFrac);
public:
// constructor
VertexLoader();
~VertexLoader();
// run the pipeline
static void SetVArray(DecodedVArray *_varray);
void Setup();
void PrepareRun();
void RunVertices(int count);
void WriteCall(TPipelineFunction func);
int GetVertexSize(){return m_VertexSize;}
//VtxDesc - global
static void SetVtxDesc_Lo(u32 _iValue)
{
u64 old = m_VtxDesc.Hex;
m_VtxDesc.Hex &= ~0x1FFFF; // keep the Upper bits
m_VtxDesc.Hex |= _iValue;
if (m_VtxDesc.Hex != old)
m_DescDirty = true;
};
static void SetVtxDesc_Hi(u32 _iValue)
{
u64 old = m_VtxDesc.Hex;
m_VtxDesc.Hex &= 0x1FFFF; // keep the lower 17Bits
m_VtxDesc.Hex |= (u64)_iValue << 17;
if (m_VtxDesc.Hex != old)
m_DescDirty = true;
};
static TVtxDesc &GetVtxDesc() {return m_VtxDesc;}
void SetVAT_group0(u32 _group0)
{
if (m_group0.Hex == _group0)
return;
m_AttrDirty = true;
m_group0.Hex = _group0;
m_VtxAttr.PosElements = m_group0.PosElements;
m_VtxAttr.PosFormat = m_group0.PosFormat;
m_VtxAttr.PosFrac = m_group0.PosFrac;
m_VtxAttr.NormalElements = m_group0.NormalElements;
m_VtxAttr.NormalFormat = m_group0.NormalFormat;
m_VtxAttr.color[0].Elements = m_group0.Color0Elements;
m_VtxAttr.color[0].Comp = m_group0.Color0Comp;
m_VtxAttr.color[1].Elements = m_group0.Color1Elements;
m_VtxAttr.color[1].Comp = m_group0.Color1Comp;
m_VtxAttr.texCoord[0].Elements = m_group0.Tex0CoordElements;
m_VtxAttr.texCoord[0].Format = m_group0.Tex0CoordFormat;
m_VtxAttr.texCoord[0].Frac = m_group0.Tex0Frac;
m_VtxAttr.ByteDequant = m_group0.ByteDequant;
m_VtxAttr.NormalIndex3 = m_group0.NormalIndex3;
};
void SetVAT_group1(u32 _group1)
{
if (m_group1.Hex == _group1)
return;
m_AttrDirty = true;
m_group1.Hex = _group1;
m_VtxAttr.texCoord[1].Elements = m_group1.Tex1CoordElements;
m_VtxAttr.texCoord[1].Format = m_group1.Tex1CoordFormat;
m_VtxAttr.texCoord[1].Frac = m_group1.Tex1Frac;
m_VtxAttr.texCoord[2].Elements = m_group1.Tex2CoordElements;
m_VtxAttr.texCoord[2].Format = m_group1.Tex2CoordFormat;
m_VtxAttr.texCoord[2].Frac = m_group1.Tex2Frac;
m_VtxAttr.texCoord[3].Elements = m_group1.Tex3CoordElements;
m_VtxAttr.texCoord[3].Format = m_group1.Tex3CoordFormat;
m_VtxAttr.texCoord[3].Frac = m_group1.Tex3Frac;
m_VtxAttr.texCoord[4].Elements = m_group1.Tex4CoordElements;
m_VtxAttr.texCoord[4].Format = m_group1.Tex4CoordFormat;
};
void SetVAT_group2(u32 _group2)
{
if (m_group2.Hex == _group2)
return;
m_AttrDirty = true;
m_group2.Hex = _group2;
m_VtxAttr.texCoord[4].Frac = m_group2.Tex4Frac;
m_VtxAttr.texCoord[5].Elements = m_group2.Tex5CoordElements;
m_VtxAttr.texCoord[5].Format = m_group2.Tex5CoordFormat;
m_VtxAttr.texCoord[5].Frac = m_group2.Tex5Frac;
m_VtxAttr.texCoord[6].Elements = m_group2.Tex6CoordElements;
m_VtxAttr.texCoord[6].Format = m_group2.Tex6CoordFormat;
m_VtxAttr.texCoord[6].Frac = m_group2.Tex6Frac;
m_VtxAttr.texCoord[7].Elements = m_group2.Tex7CoordElements;
m_VtxAttr.texCoord[7].Format = m_group2.Tex7CoordFormat;
m_VtxAttr.texCoord[7].Frac = m_group2.Tex7Frac;
};
};
extern VertexLoader g_VertexLoaders[8];
extern DecodedVArray* varray;
#endif

View File

@ -15,42 +15,142 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "VideoCommon.h"
#include "VertexLoader.h"
#include "VertexManager.h"
#include <map>
DecodedVArray tempvarray;
#include "Statistics.h"
#include "VertexShaderManager.h"
#include "VertexLoader.h"
#include "VertexLoaderManager.h"
static int s_attr_dirty; // bitfield
static VertexLoader *g_VertexLoaders[8];
namespace VertexLoaderManager
{
typedef std::map<VertexLoaderUID, VertexLoader *> VertexLoaderMap;
static VertexLoaderMap g_VertexLoaderMap;
// TODO - change into array of pointers. Keep a map of all seen so far.
void Init()
{
tempvarray.Create(65536*3, 1, 8, 3, 2, 8);
MarkAllDirty();
for (int i = 0; i < 8; i++)
g_VertexLoaders[i] = NULL;
}
void Shutdown()
{
tempvarray.Destroy();
for (VertexLoaderMap::iterator iter = g_VertexLoaderMap.begin(); iter != g_VertexLoaderMap.end(); ++iter)
{
delete iter->second;
}
g_VertexLoaderMap.clear();
}
int GetVertexSize(int vat)
void AppendListToString(std::string *dest)
{
VertexLoader& vtxLoader = g_VertexLoaders[vat];
vtxLoader.Setup();
return vtxLoader.GetVertexSize();
for (VertexLoaderMap::iterator iter = g_VertexLoaderMap.begin(); iter != g_VertexLoaderMap.end(); ++iter)
{
iter->second->AppendToString(dest);
}
}
void RunVertices(int vat, int primitive, int num_vertices)
void MarkAllDirty()
{
tempvarray.Reset();
VertexLoader::SetVArray(&tempvarray);
VertexLoader& vtxLoader = g_VertexLoaders[vat];
vtxLoader.Setup();
vtxLoader.PrepareRun();
int vsize = vtxLoader.GetVertexSize();
vtxLoader.RunVertices(num_vertices);
VertexManager::AddVertices(primitive, num_vertices, &tempvarray);
s_attr_dirty = 0xff;
}
static void RefreshLoader(int vtx_attr_group)
{
if ((s_attr_dirty >> vtx_attr_group) & 1)
{
VertexLoaderUID uid;
uid.InitFromCurrentState(vtx_attr_group);
VertexLoaderMap::iterator iter = g_VertexLoaderMap.find(uid);
if (iter != g_VertexLoaderMap.end())
{
g_VertexLoaders[vtx_attr_group] = iter->second;
}
else
{
VertexLoader *loader = new VertexLoader(g_VtxDesc, g_VtxAttr[vtx_attr_group]);
g_VertexLoaderMap[uid] = loader;
g_VertexLoaders[vtx_attr_group] = loader;
INCSTAT(stats.numVertexLoaders);
}
}
s_attr_dirty &= ~(1 << vtx_attr_group);
}
void RunVertices(int vtx_attr_group, int primitive, int count)
{
if (!count)
return;
RefreshLoader(vtx_attr_group);
g_VertexLoaders[vtx_attr_group]->RunVertices(vtx_attr_group, primitive, count);
}
int GetVertexSize(int vtx_attr_group)
{
RefreshLoader(vtx_attr_group);
return g_VertexLoaders[vtx_attr_group]->GetVertexSize();
}
} // namespace
void LoadCPReg(u32 sub_cmd, u32 value)
{
switch (sub_cmd & 0xF0)
{
case 0x30:
VertexShaderManager::SetTexMatrixChangedA(value);
break;
case 0x40:
VertexShaderManager::SetTexMatrixChangedB(value);
break;
case 0x50:
g_VtxDesc.Hex &= ~0x1FFFF; // keep the Upper bits
g_VtxDesc.Hex |= value;
s_attr_dirty = 0xFF;
break;
case 0x60:
g_VtxDesc.Hex &= 0x1FFFF; // keep the lower 17Bits
g_VtxDesc.Hex |= (u64)value << 17;
s_attr_dirty = 0xFF;
break;
case 0x70:
_assert_((sub_cmd & 0x0F) < 8);
g_VtxAttr[sub_cmd & 7].g0.Hex = value;
s_attr_dirty |= 1 << (sub_cmd & 7);
break;
case 0x80:
_assert_((sub_cmd & 0x0F) < 8);
g_VtxAttr[sub_cmd & 7].g1.Hex = value;
s_attr_dirty |= 1 << (sub_cmd & 7);
break;
case 0x90:
_assert_((sub_cmd & 0x0F) < 8);
g_VtxAttr[sub_cmd & 7].g2.Hex = value;
s_attr_dirty |= 1 << (sub_cmd & 7);
break;
// Pointers to vertex arrays in GC RAM
case 0xA0:
arraybases[sub_cmd & 0xF] = value & 0xFFFFFFFF; // huh, why the mask?
break;
case 0xB0:
arraystrides[sub_cmd & 0xF] = value & 0xFF;
break;
}
}

View File

@ -1,226 +0,0 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _VERTEXLOADERCOLOR_H
#define _VERTEXLOADERCOLOR_H
#include "LookUpTables.h"
#define RSHIFT 16
#define GSHIFT 8
#define BSHIFT 0
#define ASHIFT 24
extern DecodedVArray *varray;
extern int colIndex;
inline void _SetCol(u32 val)
{
varray->SetColor(colIndex, val);
colIndex++;
}
void _SetCol4444(u16 val)
{
u32 col = lut4to8[(val>>0)&0xF]<<ASHIFT;
col |= lut4to8[(val>>12)&0xF] <<RSHIFT;
col |= lut4to8[(val>>8)&0xF] <<GSHIFT;
col |= lut4to8[(val>>4)&0xF] <<BSHIFT;
_SetCol(col);
}
void _SetCol6666(u32 val)
{
u32 col = lut6to8[(val>>18)&0x3F] << RSHIFT;
col |= lut6to8[(val>>12)&0x3F] << GSHIFT;
col |= lut6to8[(val>>6)&0x3F] << BSHIFT;
col |= lut6to8[(val>>0)&0x3F] << ASHIFT;
_SetCol(col);
}
void _SetCol565(u16 val)
{
u32 col = lut5to8[(val>>11)&0x1f] << RSHIFT;
col |= lut6to8[(val>>5 )&0x3f] << GSHIFT;
col |= lut5to8[(val )&0x1f] << BSHIFT;
_SetCol(col | (0xFF<<ASHIFT));
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
inline u32 _Read24(u32 iAddress)
{
u32 col = Memory_Read_U8(iAddress) << RSHIFT; //should just get a pointer to main memory instead of going thru slow memhandler
col |= Memory_Read_U8(iAddress+1) << GSHIFT; //we can guarantee that it is reading from main memory
col |= Memory_Read_U8(iAddress+2) << BSHIFT;
return col | (0xFF<<ASHIFT);
}
inline u32 _Read32(u32 iAddress)
{
u32 col = Memory_Read_U8(iAddress) << RSHIFT; //should just get a pointer to main memory instead of going thru slow memhandler
col |= Memory_Read_U8(iAddress+1) << GSHIFT; //we can guarantee that it is reading from main memory
col |= Memory_Read_U8(iAddress+2) << BSHIFT;
col |= Memory_Read_U8(iAddress+3) << ASHIFT;
return col;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void LOADERDECL Color_ReadDirect_24b_888(const void *_p)
{
u32 col = DataReadU8()<<RSHIFT;
col |= DataReadU8()<<GSHIFT;
col |= DataReadU8()<<BSHIFT;
_SetCol(col | (0xFF<<ASHIFT));
}
void LOADERDECL Color_ReadDirect_32b_888x(const void *_p){
u32 col = DataReadU8()<<RSHIFT;
col |= DataReadU8()<<GSHIFT;
col |= DataReadU8()<<BSHIFT;
_SetCol(col | (0xFF<<ASHIFT));
DataReadU8();
}
void LOADERDECL Color_ReadDirect_16b_565(const void *_p)
{
_SetCol565(DataReadU16());
}
void LOADERDECL Color_ReadDirect_16b_4444(const void *_p)
{
_SetCol4444(DataReadU16());
}
void LOADERDECL Color_ReadDirect_24b_6666(const void *_p)
{
u32 val = DataReadU8()<<16;
val|=DataReadU8()<<8;
val|=DataReadU8();
_SetCol6666(val);
}
// F|RES: i am not 100 percent sure, but the colElements seems to be important for rendering only
// at least it fixes mario party 4
//
// if (colElements[colIndex])
// else
// col |= 0xFF<<ASHIFT;
//
void LOADERDECL Color_ReadDirect_32b_8888(const void *_p)
{
u32 col = DataReadU8()<<RSHIFT;
col |= DataReadU8()<<GSHIFT;
col |= DataReadU8()<<BSHIFT;
col |= DataReadU8()<<ASHIFT;
// "kill" the alpha
if (!colElements[colIndex])
col |= 0xFF << ASHIFT;
_SetCol(col);
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void LOADERDECL Color_ReadIndex8_16b_565(const void *_p)
{
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]);
u16 val = Memory_Read_U16(iAddress);
_SetCol565(val);
}
void LOADERDECL Color_ReadIndex8_24b_888(const void *_p)
{
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]);
_SetCol(_Read24(iAddress));
}
void LOADERDECL Color_ReadIndex8_32b_888x(const void *_p)
{
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR]+colIndex);
_SetCol(_Read24(iAddress));
}
void LOADERDECL Color_ReadIndex8_16b_4444(const void *_p)
{
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]);
u16 val = Memory_Read_U16(iAddress);
_SetCol4444(val);
}
void LOADERDECL Color_ReadIndex8_24b_6666(const void *_p)
{
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]);
u32 val = Memory_Read_U8(iAddress+2) |
(Memory_Read_U8(iAddress+1)<<8) |
(Memory_Read_U8(iAddress)<<16);
_SetCol6666(val);
}
void LOADERDECL Color_ReadIndex8_32b_8888(const void *_p)
{
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]);
_SetCol(_Read32(iAddress));
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void LOADERDECL Color_ReadIndex16_16b_565(const void *_p)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]);
u16 val = Memory_Read_U16(iAddress);
_SetCol565(val);
}
void LOADERDECL Color_ReadIndex16_24b_888(const void *_p)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]);
_SetCol(_Read24(iAddress));
}
void LOADERDECL Color_ReadIndex16_32b_888x(const void *_p)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]);
_SetCol(_Read24(iAddress));
}
void LOADERDECL Color_ReadIndex16_16b_4444(const void *_p)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]);
u16 val = Memory_Read_U16(iAddress);
_SetCol4444(val);
}
void LOADERDECL Color_ReadIndex16_24b_6666(const void *_p)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]);
u32 val = Memory_Read_U8(iAddress+2) |
(Memory_Read_U8(iAddress+1)<<8) |
(Memory_Read_U8(iAddress)<<16);
_SetCol6666(val);
}
void LOADERDECL Color_ReadIndex16_32b_8888(const void *_p)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]);
_SetCol(_Read32(iAddress));
}
#endif

View File

@ -1,41 +0,0 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#pragma once
#include "Common.h"
#include "TransformEngine.h"
// ==============================================================================
// Direct
// ==============================================================================
void LOADERDECL PosMtx_ReadDirect_UByte(const void* _p)
{
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
int index = DataReadU8() & 0x3f;
float *flipmem = (float *)xfmem;
varray->SetPosNrmIdx(index);
}
int s_texmtxread = 0, s_texmtxwrite = 0;
void LOADERDECL TexMtx_ReadDirect_UByte(const void* _p)
{
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
int index = DataReadU8() & 0x3f;
varray->SetTcIdx(s_texmtxread++, index);
}

View File

@ -1,488 +0,0 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "main.h"
#include "Utils.h"
#include "DecodedVArray.h"
#include "VertexLoader.h"
#include "VertexLoader_Normal.h"
u8 VertexLoader_Normal::m_sizeTable[NUM_NRM_TYPE][NUM_NRM_FORMAT][NUM_NRM_ELEMENTS];
TPipelineFunction VertexLoader_Normal::m_funcTable[NUM_NRM_TYPE][NUM_NRM_FORMAT][NUM_NRM_ELEMENTS];
bool VertexLoader_Normal::index3;
// __________________________________________________________________________________________________
// Init
//
void VertexLoader_Normal::Init(void)
{
// size table
m_sizeTable[NRM_DIRECT][FORMAT_UBYTE] [NRM_NBT] = 3;
m_sizeTable[NRM_DIRECT][FORMAT_BYTE] [NRM_NBT] = 3;
m_sizeTable[NRM_DIRECT][FORMAT_USHORT][NRM_NBT] = 6;
m_sizeTable[NRM_DIRECT][FORMAT_SHORT] [NRM_NBT] = 6;
m_sizeTable[NRM_DIRECT][FORMAT_FLOAT] [NRM_NBT] = 12;
m_sizeTable[NRM_DIRECT][FORMAT_UBYTE] [NRM_NBT3] = 9;
m_sizeTable[NRM_DIRECT][FORMAT_BYTE] [NRM_NBT3] = 9;
m_sizeTable[NRM_DIRECT][FORMAT_USHORT][NRM_NBT3] = 18;
m_sizeTable[NRM_DIRECT][FORMAT_SHORT] [NRM_NBT3] = 18;
m_sizeTable[NRM_DIRECT][FORMAT_FLOAT] [NRM_NBT3] = 36;
m_sizeTable[NRM_INDEX8][FORMAT_UBYTE] [NRM_NBT] = 1;
m_sizeTable[NRM_INDEX8][FORMAT_BYTE] [NRM_NBT] = 1;
m_sizeTable[NRM_INDEX8][FORMAT_USHORT][NRM_NBT] = 1;
m_sizeTable[NRM_INDEX8][FORMAT_SHORT] [NRM_NBT] = 1;
m_sizeTable[NRM_INDEX8][FORMAT_FLOAT] [NRM_NBT] = 1;
m_sizeTable[NRM_INDEX8][FORMAT_UBYTE] [NRM_NBT3] = 3;
m_sizeTable[NRM_INDEX8][FORMAT_BYTE] [NRM_NBT3] = 3;
m_sizeTable[NRM_INDEX8][FORMAT_USHORT][NRM_NBT3] = 3;
m_sizeTable[NRM_INDEX8][FORMAT_SHORT] [NRM_NBT3] = 3;
m_sizeTable[NRM_INDEX8][FORMAT_FLOAT] [NRM_NBT3] = 3;
m_sizeTable[NRM_INDEX16][FORMAT_UBYTE] [NRM_NBT] = 2;
m_sizeTable[NRM_INDEX16][FORMAT_BYTE] [NRM_NBT] = 2;
m_sizeTable[NRM_INDEX16][FORMAT_USHORT][NRM_NBT] = 2;
m_sizeTable[NRM_INDEX16][FORMAT_SHORT] [NRM_NBT] = 2;
m_sizeTable[NRM_INDEX16][FORMAT_FLOAT] [NRM_NBT] = 2;
m_sizeTable[NRM_INDEX16][FORMAT_UBYTE] [NRM_NBT3] = 6;
m_sizeTable[NRM_INDEX16][FORMAT_BYTE] [NRM_NBT3] = 6;
m_sizeTable[NRM_INDEX16][FORMAT_USHORT][NRM_NBT3] = 6;
m_sizeTable[NRM_INDEX16][FORMAT_SHORT] [NRM_NBT3] = 6;
m_sizeTable[NRM_INDEX16][FORMAT_FLOAT] [NRM_NBT3] = 6;
// function table
m_funcTable[NRM_DIRECT][FORMAT_UBYTE] [NRM_NBT] = Normal_DirectByte; //HACK
m_funcTable[NRM_DIRECT][FORMAT_BYTE] [NRM_NBT] = Normal_DirectByte;
m_funcTable[NRM_DIRECT][FORMAT_USHORT][NRM_NBT] = Normal_DirectShort; //HACK
m_funcTable[NRM_DIRECT][FORMAT_SHORT] [NRM_NBT] = Normal_DirectShort;
m_funcTable[NRM_DIRECT][FORMAT_FLOAT] [NRM_NBT] = Normal_DirectFloat;
m_funcTable[NRM_DIRECT][FORMAT_UBYTE] [NRM_NBT3] = Normal_DirectByte3; //HACK
m_funcTable[NRM_DIRECT][FORMAT_BYTE] [NRM_NBT3] = Normal_DirectByte3;
m_funcTable[NRM_DIRECT][FORMAT_USHORT][NRM_NBT3] = Normal_DirectShort3; //HACK
m_funcTable[NRM_DIRECT][FORMAT_SHORT] [NRM_NBT3] = Normal_DirectShort3;
m_funcTable[NRM_DIRECT][FORMAT_FLOAT] [NRM_NBT3] = Normal_DirectFloat3;
m_funcTable[NRM_INDEX8][FORMAT_UBYTE] [NRM_NBT] = Normal_Index8_Byte; //HACK
m_funcTable[NRM_INDEX8][FORMAT_BYTE] [NRM_NBT] = Normal_Index8_Byte;
m_funcTable[NRM_INDEX8][FORMAT_USHORT][NRM_NBT] = Normal_Index8_Short; //HACK
m_funcTable[NRM_INDEX8][FORMAT_SHORT] [NRM_NBT] = Normal_Index8_Short;
m_funcTable[NRM_INDEX8][FORMAT_FLOAT] [NRM_NBT] = Normal_Index8_Float;
m_funcTable[NRM_INDEX8][FORMAT_UBYTE] [NRM_NBT3] = Normal_Index8_Byte3; //HACK
m_funcTable[NRM_INDEX8][FORMAT_BYTE] [NRM_NBT3] = Normal_Index8_Byte3;
m_funcTable[NRM_INDEX8][FORMAT_USHORT][NRM_NBT3] = Normal_Index8_Short3; //HACK
m_funcTable[NRM_INDEX8][FORMAT_SHORT] [NRM_NBT3] = Normal_Index8_Short3;
m_funcTable[NRM_INDEX8][FORMAT_FLOAT] [NRM_NBT3] = Normal_Index8_Float3;
m_funcTable[NRM_INDEX16][FORMAT_UBYTE] [NRM_NBT] = Normal_Index16_Byte; //HACK
m_funcTable[NRM_INDEX16][FORMAT_BYTE] [NRM_NBT] = Normal_Index16_Byte;
m_funcTable[NRM_INDEX16][FORMAT_USHORT][NRM_NBT] = Normal_Index16_Short; //HACK
m_funcTable[NRM_INDEX16][FORMAT_SHORT] [NRM_NBT] = Normal_Index16_Short;
m_funcTable[NRM_INDEX16][FORMAT_FLOAT] [NRM_NBT] = Normal_Index16_Float;
m_funcTable[NRM_INDEX16][FORMAT_UBYTE] [NRM_NBT3] = Normal_Index16_Byte3; //HACK
m_funcTable[NRM_INDEX16][FORMAT_BYTE] [NRM_NBT3] = Normal_Index16_Byte3;
m_funcTable[NRM_INDEX16][FORMAT_USHORT][NRM_NBT3] = Normal_Index16_Short3; //HACK
m_funcTable[NRM_INDEX16][FORMAT_SHORT] [NRM_NBT3] = Normal_Index16_Short3;
m_funcTable[NRM_INDEX16][FORMAT_FLOAT] [NRM_NBT3] = Normal_Index16_Float3;
}
// __________________________________________________________________________________________________
// GetSize
//
unsigned int
VertexLoader_Normal::GetSize(unsigned int _type, unsigned int _format, unsigned int _elements)
{
return m_sizeTable[_type][_format][_elements];
}
// __________________________________________________________________________________________________
// GetFunction
//
TPipelineFunction
VertexLoader_Normal::GetFunction(unsigned int _type, unsigned int _format, unsigned int _elements)
{
TPipelineFunction pFunc = m_funcTable[_type][_format][_elements];
return pFunc;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// --- Direct ---
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
// __________________________________________________________________________________________________
// Normal_DirectByte
//
void LOADERDECL
VertexLoader_Normal::Normal_DirectByte(const void* _p)
{
varray->SetNormalX(0, ((float)(signed char)DataReadU8()+0.5f) / 127.5f);
varray->SetNormalY(0, ((float)(signed char)DataReadU8()+0.5f) / 127.5f);
varray->SetNormalZ(0, ((float)(signed char)DataReadU8()+0.5f) / 127.5f);
}
// __________________________________________________________________________________________________
// Normal_DirectShort
//
void LOADERDECL
VertexLoader_Normal::Normal_DirectShort(const void* _p)
{
varray->SetNormalX(0, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f);
varray->SetNormalY(0, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f);
varray->SetNormalZ(0, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f);
}
// __________________________________________________________________________________________________
// Normal_DirectFloat
//
void LOADERDECL
VertexLoader_Normal::Normal_DirectFloat(const void* _p)
{
varray->SetNormalX(0, DataReadF32());
varray->SetNormalY(0, DataReadF32());
varray->SetNormalZ(0, DataReadF32());
}
// __________________________________________________________________________________________________
// Normal_DirectByte3
//
void LOADERDECL
VertexLoader_Normal::Normal_DirectByte3(const void* _p)
{
for (int i=0; i<3; i++)
{
varray->SetNormalX(i, ((float)(signed char)DataReadU8()+0.5f) / 127.5f);
varray->SetNormalY(i, ((float)(signed char)DataReadU8()+0.5f) / 127.5f);
varray->SetNormalZ(i, ((float)(signed char)DataReadU8()+0.5f) / 127.5f);
}
}
// __________________________________________________________________________________________________
// Normal_DirectShort3
//
void LOADERDECL
VertexLoader_Normal::Normal_DirectShort3(const void* _p)
{
for (int i=0; i<3; i++)
{
varray->SetNormalX(i, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f);
varray->SetNormalY(i, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f);
varray->SetNormalZ(i, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f);
}
}
// __________________________________________________________________________________________________
// Normal_DirectFloat3
//
void LOADERDECL
VertexLoader_Normal::Normal_DirectFloat3(const void* _p)
{
for (int i=0; i<3; i++)
{
varray->SetNormalX(i, DataReadF32());
varray->SetNormalY(i, DataReadF32());
varray->SetNormalZ(i, DataReadF32());
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// --- Index8 ---
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
// __________________________________________________________________________________________________
// Normal_Index8_Byte
//
void LOADERDECL
VertexLoader_Normal::Normal_Index8_Byte(const void* _p)
{
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]);
varray->SetNormalX(0, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f);
varray->SetNormalY(0, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f);
varray->SetNormalZ(0, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f);
}
// __________________________________________________________________________________________________
// Normal_Index8_Short
//
void LOADERDECL
VertexLoader_Normal::Normal_Index8_Short(const void* _p)
{
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]);
varray->SetNormalX(0, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f);
varray->SetNormalY(0, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f);
varray->SetNormalZ(0, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f);
}
// __________________________________________________________________________________________________
// Normal_Index8_Float
//
void LOADERDECL
VertexLoader_Normal::Normal_Index8_Float(const void* _p)
{
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]);
varray->SetNormalX(0, Memory_Read_Float(iAddress));
varray->SetNormalY(0, Memory_Read_Float(iAddress+4));
varray->SetNormalZ(0, Memory_Read_Float(iAddress+8));
}
// __________________________________________________________________________________________________
// Normal_Index8_Byte3
//
void LOADERDECL
VertexLoader_Normal::Normal_Index8_Byte3(const void* _p)
{
if (index3)
{
for (int i=0; i<3; i++)
{
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i;
varray->SetNormalX(i, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f);
varray->SetNormalY(i, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f);
varray->SetNormalZ(i, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f);
}
}
else
{
u8 Index = DataReadU8();
for (int i=0; i<3; i++)
{
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i;
varray->SetNormalX(i, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f);
varray->SetNormalY(i, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f);
varray->SetNormalZ(i, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f);
}
}
}
// __________________________________________________________________________________________________
// Normal_Index8_Short3
//
void LOADERDECL
VertexLoader_Normal::Normal_Index8_Short3(const void* _p)
{
if (index3)
{
for (int i=0; i<3; i++)
{
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i;
varray->SetNormalX(i, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f);
varray->SetNormalY(i, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f);
varray->SetNormalZ(i, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f);
}
}
else
{
u8 Index = DataReadU8();
for (int i=0; i<3; i++)
{
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i;
varray->SetNormalX(i, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f);
varray->SetNormalY(i, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f);
varray->SetNormalZ(i, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f);
}
}
}
// __________________________________________________________________________________________________
// Normal_Index8_Float3
//
void LOADERDECL
VertexLoader_Normal::Normal_Index8_Float3(const void* _p)
{
if (index3)
{
for (int i=0; i<3; i++)
{
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i;
varray->SetNormalX(i, Memory_Read_Float(iAddress));
varray->SetNormalY(i, Memory_Read_Float(iAddress+4));
varray->SetNormalZ(i, Memory_Read_Float(iAddress+8));
}
}
else
{
u8 Index = DataReadU8();
for (int i=0; i<3; i++)
{
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i;
varray->SetNormalX(i, Memory_Read_Float(iAddress));
varray->SetNormalY(i, Memory_Read_Float(iAddress+4));
varray->SetNormalZ(i, Memory_Read_Float(iAddress+8));
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// --- Index16 ---
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
// __________________________________________________________________________________________________
// Normal_Index16_Byte
//
void LOADERDECL
VertexLoader_Normal::Normal_Index16_Byte(const void* _p)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]);
varray->SetNormalX(0, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f);
varray->SetNormalY(0, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f);
varray->SetNormalZ(0, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f);
}
// __________________________________________________________________________________________________
// Normal_Index16_Short
//
void LOADERDECL
VertexLoader_Normal::Normal_Index16_Short(const void* _p)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]);
varray->SetNormalX(0, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f);
varray->SetNormalY(0, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f);
varray->SetNormalZ(0, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f);
}
// __________________________________________________________________________________________________
// Normal_Index8_Float
//
void LOADERDECL
VertexLoader_Normal::Normal_Index16_Float(const void* _p)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]);
varray->SetNormalX(0, Memory_Read_Float(iAddress));
varray->SetNormalY(0, Memory_Read_Float(iAddress+4));
varray->SetNormalZ(0, Memory_Read_Float(iAddress+8));
}
// __________________________________________________________________________________________________
// Normal_Index16_Byte3
//
void LOADERDECL
VertexLoader_Normal::Normal_Index16_Byte3(const void* _p)
{
if (index3)
{
for (int i=0; i<3; i++)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i;
varray->SetNormalX(i, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f);
varray->SetNormalY(i, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f);
varray->SetNormalZ(i, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f);
}
}
else
{
u16 Index = DataReadU16();
for (int i=0; i<3; i++)
{
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i;
varray->SetNormalX(i, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f);
varray->SetNormalY(i, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f);
varray->SetNormalZ(i, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f);
}
}
}
// __________________________________________________________________________________________________
// Normal_Index16_Short3
//
void LOADERDECL
VertexLoader_Normal::Normal_Index16_Short3(const void* _p)
{
if (index3)
{
for (int i=0; i<3; i++)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i;
varray->SetNormalX(i, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f);
varray->SetNormalY(i, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f);
varray->SetNormalZ(i, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f);
}
}
else
{
u16 Index = DataReadU16();
for (int i=0; i<3; i++)
{
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i;
varray->SetNormalX(i, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f);
varray->SetNormalY(i, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f);
varray->SetNormalZ(i, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f);
}
}
}
// __________________________________________________________________________________________________
// Normal_Index16_Float3
//
void LOADERDECL
VertexLoader_Normal::Normal_Index16_Float3(const void* _p)
{
if (index3)
{
for (int i=0; i<3; i++)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i;
varray->SetNormalX(i, Memory_Read_Float(iAddress ));
varray->SetNormalY(i, Memory_Read_Float(iAddress+4));
varray->SetNormalZ(i, Memory_Read_Float(iAddress+8));
}
}
else
{
u16 Index = DataReadU16();
for (int i=0; i<3; i++)
{
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i;
varray->SetNormalX(i, Memory_Read_Float(iAddress ));
varray->SetNormalY(i, Memory_Read_Float(iAddress+4));
varray->SetNormalZ(i, Memory_Read_Float(iAddress+8));
}
}
}

View File

@ -1,90 +0,0 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#pragma once
#include "CommonTypes.h"
class VertexLoader_Normal
{
public:
static bool index3;
// Init
static void Init(void);
// GetSize
static unsigned int GetSize(unsigned int _type, unsigned int _format, unsigned int _elements);
// GetFunction
static TPipelineFunction GetFunction(unsigned int _type, unsigned int _format, unsigned int _elements);
private:
enum ENormalType
{
NRM_NOT_PRESENT = 0,
NRM_DIRECT = 1,
NRM_INDEX8 = 2,
NRM_INDEX16 = 3,
NUM_NRM_TYPE
};
enum ENormalFormat
{
FORMAT_UBYTE = 0,
FORMAT_BYTE = 1,
FORMAT_USHORT = 2,
FORMAT_SHORT = 3,
FORMAT_FLOAT = 4,
NUM_NRM_FORMAT
};
enum ENormalElements
{
NRM_NBT = 0,
NRM_NBT3 = 1,
NUM_NRM_ELEMENTS
};
// tables
static u8 m_sizeTable[NUM_NRM_TYPE][NUM_NRM_FORMAT][NUM_NRM_ELEMENTS];
static TPipelineFunction m_funcTable[NUM_NRM_TYPE][NUM_NRM_FORMAT][NUM_NRM_ELEMENTS];
// direct
static void LOADERDECL Normal_DirectByte(const void* _p);
static void LOADERDECL Normal_DirectShort(const void* _p);
static void LOADERDECL Normal_DirectFloat(const void* _p);
static void LOADERDECL Normal_DirectByte3(const void* _p);
static void LOADERDECL Normal_DirectShort3(const void* _p);
static void LOADERDECL Normal_DirectFloat3(const void* _p);
// index8
static void LOADERDECL Normal_Index8_Byte(const void* _p);
static void LOADERDECL Normal_Index8_Short(const void* _p);
static void LOADERDECL Normal_Index8_Float(const void* _p);
static void LOADERDECL Normal_Index8_Byte3(const void* _p);
static void LOADERDECL Normal_Index8_Short3(const void* _p);
static void LOADERDECL Normal_Index8_Float3(const void* _p);
// index16
static void LOADERDECL Normal_Index16_Byte(const void* _p);
static void LOADERDECL Normal_Index16_Short(const void* _p);
static void LOADERDECL Normal_Index16_Float(const void* _p);
static void LOADERDECL Normal_Index16_Byte3(const void* _p);
static void LOADERDECL Normal_Index16_Short3(const void* _p);
static void LOADERDECL Normal_Index16_Float3(const void* _p);
};

View File

@ -1,213 +0,0 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef VERTEXHANDLER_POSITION_H
#define VERTEXHANDLER_POSITION_H
#include "Common.h"
#include "Utils.h"
// ==============================================================================
// Direct
// ==============================================================================
template<class T>
inline void LOADERDECL _ReadPos8Mem(int iAddress, TVtxAttr* pVtxAttr)
{
varray->SetPosX(((float)(T)Memory_Read_U8(iAddress)) * posScale);
varray->SetPosY(((float)(T)Memory_Read_U8(iAddress+1)) * posScale);
if (pVtxAttr->PosElements)
varray->SetPosZ(((float)(T)Memory_Read_U8(iAddress+2)) * posScale);
else
varray->SetPosZ(1.0);
}
template<class T>
inline void LOADERDECL _ReadPos16Mem(int iAddress, TVtxAttr* pVtxAttr)
{
varray->SetPosX(((float)(T)Memory_Read_U16(iAddress)) * posScale);
varray->SetPosY(((float)(T)Memory_Read_U16(iAddress+2)) * posScale);
if (pVtxAttr->PosElements)
varray->SetPosZ(((float)(T)Memory_Read_U16(iAddress+4)) * posScale);
else
varray->SetPosZ(1.0);
}
void LOADERDECL _ReadPosFloatMem(int iAddress, TVtxAttr* pVtxAttr)
{
u32 uTemp;
uTemp = Memory_Read_U32(iAddress );
varray->SetPosX(*(float*)&uTemp);
uTemp = Memory_Read_U32(iAddress+4);
varray->SetPosY(*(float*)&uTemp);
if (pVtxAttr->PosElements)
{
uTemp = Memory_Read_U32(iAddress+8);
varray->SetPosZ(*(float*)&uTemp);
}
else
varray->SetPosZ(1.0);
}
void LOADERDECL Pos_ReadDirect_UByte(const void* _p)
{
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
varray->SetPosX((float)DataReadU8() * posScale);
varray->SetPosY((float)DataReadU8() * posScale);
if (pVtxAttr->PosElements)
varray->SetPosZ((float)DataReadU8() * posScale);
else
varray->SetPosZ(1.0);
}
void LOADERDECL Pos_ReadDirect_Byte(const void* _p)
{
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
varray->SetPosX((float)(s8)DataReadU8() * posScale);
varray->SetPosY((float)(s8)DataReadU8() * posScale);
if (pVtxAttr->PosElements)
varray->SetPosZ((float)(s8)DataReadU8() * posScale);
else
varray->SetPosZ(1.0);
}
void LOADERDECL Pos_ReadDirect_UShort(const void* _p)
{
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
varray->SetPosX((float)DataReadU16() * posScale);
varray->SetPosY((float)DataReadU16() * posScale);
if (pVtxAttr->PosElements)
varray->SetPosZ((float)DataReadU16() * posScale);
else
varray->SetPosZ(1.0);
}
void LOADERDECL Pos_ReadDirect_Short(const void* _p)
{
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
varray->SetPosX((float)(s16)DataReadU16() * posScale);
varray->SetPosY((float)(s16)DataReadU16() * posScale);
if (pVtxAttr->PosElements)
varray->SetPosZ((float)(s16)DataReadU16() * posScale);
else
varray->SetPosZ(1.0);
}
void LOADERDECL Pos_ReadDirect_Float(const void* _p)
{
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
varray->SetPosX(DataReadF32());
varray->SetPosY(DataReadF32());
if (pVtxAttr->PosElements)
varray->SetPosZ(DataReadF32());
else
varray->SetPosZ(1.0);
}
// ==============================================================================
// Index 8
// ==============================================================================
void LOADERDECL Pos_ReadIndex8_UByte(const void* _p)
{
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_POSITION] + (Index * arraystrides[ARRAY_POSITION]);
_ReadPos8Mem<u8>(iAddress, pVtxAttr);
}
void LOADERDECL Pos_ReadIndex8_Byte(const void* _p)
{
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_POSITION] + (Index * arraystrides[ARRAY_POSITION]);
_ReadPos8Mem<s8>(iAddress, pVtxAttr);
}
void LOADERDECL Pos_ReadIndex8_UShort(const void* _p)
{
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_POSITION] + (Index * arraystrides[ARRAY_POSITION]);
_ReadPos16Mem<u16>(iAddress, pVtxAttr);
}
void LOADERDECL Pos_ReadIndex8_Short(const void* _p)
{
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_POSITION] + (Index * arraystrides[ARRAY_POSITION]);
_ReadPos16Mem<s16>(iAddress, pVtxAttr);
}
void LOADERDECL Pos_ReadIndex8_Float(const void* _p)
{
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_POSITION] + (Index * arraystrides[ARRAY_POSITION]);
_ReadPosFloatMem(iAddress, pVtxAttr);
}
// ==============================================================================
// Index 16
// ==============================================================================
void LOADERDECL Pos_ReadIndex16_UByte(const void* _p){
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_POSITION] + (Index * arraystrides[ARRAY_POSITION]);
_ReadPos8Mem<u8>(iAddress, pVtxAttr);
}
void LOADERDECL Pos_ReadIndex16_Byte(const void* _p){
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_POSITION] + (Index * arraystrides[ARRAY_POSITION]);
_ReadPos8Mem<s8>(iAddress, pVtxAttr);
}
void LOADERDECL Pos_ReadIndex16_UShort(const void* _p){
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_POSITION] + (Index * arraystrides[ARRAY_POSITION]);
_ReadPos16Mem<u16>(iAddress, pVtxAttr);
}
void LOADERDECL Pos_ReadIndex16_Short(const void* _p)
{
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_POSITION] + (Index * arraystrides[ARRAY_POSITION]);
_ReadPos16Mem<s16>(iAddress, pVtxAttr);
}
void LOADERDECL Pos_ReadIndex16_Float(const void* _p)
{
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_POSITION] + (Index * arraystrides[ARRAY_POSITION]);
_ReadPosFloatMem(iAddress, pVtxAttr);
}
#endif

View File

@ -1,202 +0,0 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef VERTEXHANDLER_TEXCOORD_H
#define VERTEXHANDLER_TEXCOORD_H
extern int tcIndex;
void LOADERDECL TexCoord_ReadDirect_UByte(const void* _p)
{
varray->SetU(tcIndex, DataReadU8() * tcScaleU[tcIndex]);
if (tcElements[tcIndex])
varray->SetV(tcIndex, DataReadU8() * tcScaleV[tcIndex]);
tcIndex++;
}
void LOADERDECL TexCoord_ReadDirect_Byte(const void* _p)
{
varray->SetU(tcIndex, (s8)DataReadU8() * tcScaleU[tcIndex]);
if (tcElements[tcIndex])
varray->SetV(tcIndex, (s8)DataReadU8() * tcScaleV[tcIndex]);
tcIndex++;
}
void LOADERDECL TexCoord_ReadDirect_UShort(const void* _p)
{
varray->SetU(tcIndex, DataReadU16() * tcScaleU[tcIndex]);
if (tcElements[tcIndex])
varray->SetV(tcIndex, DataReadU16() * tcScaleV[tcIndex]);
tcIndex++;
}
void LOADERDECL TexCoord_ReadDirect_Short(const void* _p)
{
varray->SetU(tcIndex, (s16)DataReadU16() * tcScaleU[tcIndex]);
if (tcElements[tcIndex])
varray->SetV(tcIndex, (s16)DataReadU16() * tcScaleV[tcIndex]);
tcIndex++;
}
void LOADERDECL TexCoord_ReadDirect_Float(const void* _p)
{
varray->SetU(tcIndex, DataReadF32() * tcScaleU[tcIndex]);
if (tcElements[tcIndex])
varray->SetV(tcIndex, DataReadF32() * tcScaleV[tcIndex]);
tcIndex++;
}
// ==================================================================================
void LOADERDECL TexCoord_ReadIndex8_UByte(const void* _p)
{
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]);
varray->SetU(tcIndex, (float)(u8)Memory_Read_U8(iAddress) * tcScaleU[tcIndex]);
if (tcElements[tcIndex])
varray->SetV(tcIndex, (float)(u8)Memory_Read_U8(iAddress+1) * tcScaleV[tcIndex]);
tcIndex++;
}
void LOADERDECL TexCoord_ReadIndex8_Byte(const void* _p)
{
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]);
varray->SetU(tcIndex, (float)(s8)Memory_Read_U8(iAddress) * tcScaleU[tcIndex]);
if (tcElements[tcIndex])
varray->SetV(tcIndex, (float)(s8)Memory_Read_U8(iAddress+1) * tcScaleV[tcIndex]);
tcIndex++;
}
void LOADERDECL TexCoord_ReadIndex8_UShort(const void* _p)
{
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]);
varray->SetU(tcIndex, (float)(u16)Memory_Read_U16(iAddress) * tcScaleU[tcIndex]);
if (tcElements[tcIndex])
varray->SetV(tcIndex, (float)(u16)Memory_Read_U16(iAddress+2) * tcScaleV[tcIndex]);
tcIndex++;
}
void LOADERDECL TexCoord_ReadIndex8_Short(const void* _p)
{
u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]);
varray->SetU(tcIndex, (float)(s16)Memory_Read_U16(iAddress) * tcScaleU[tcIndex]);
if (tcElements[tcIndex])
varray->SetV(tcIndex, (float)(s16)Memory_Read_U16(iAddress+2) * tcScaleV[tcIndex]);
tcIndex++;
}
void LOADERDECL TexCoord_ReadIndex8_Float(const void* _p)
{
u16 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]);
u32 uTemp;
uTemp = Memory_Read_U32(iAddress );
varray->SetU(tcIndex, *(float*)&uTemp * tcScaleU[tcIndex]);
if (tcElements[tcIndex])
{
uTemp = Memory_Read_U32(iAddress+4);
varray->SetV(tcIndex, *(float*)&uTemp * tcScaleV[tcIndex]);
}
tcIndex++;
}
// ==================================================================================
void LOADERDECL TexCoord_ReadIndex16_UByte(const void* _p)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]);
u32 uTemp;
uTemp = (u8)Memory_Read_U8(iAddress );
varray->SetU(tcIndex, float(uTemp)* tcScaleU[tcIndex]);
if (tcElements[tcIndex])
{
uTemp = (u8)Memory_Read_U8(iAddress+1);
varray->SetV(tcIndex, float(uTemp)* tcScaleV[tcIndex]);
}
tcIndex++;
}
void LOADERDECL TexCoord_ReadIndex16_Byte(const void* _p)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]);
u32 uTemp;
uTemp = (s8)Memory_Read_U8(iAddress );
varray->SetU(tcIndex, float(uTemp)* tcScaleU[tcIndex]);
if (tcElements[tcIndex])
{
uTemp = (s8)Memory_Read_U8(iAddress+1);
varray->SetV(tcIndex, float(uTemp)* tcScaleV[tcIndex]);
}
tcIndex++;
}
void LOADERDECL TexCoord_ReadIndex16_UShort(const void* _p)
{
TVtxAttr* pVtxAttr = (TVtxAttr*)_p;
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]);
float uTemp;
uTemp = (float)(u16)Memory_Read_U16(iAddress );
varray->SetU(tcIndex, uTemp * tcScaleU[tcIndex]);
if (tcElements[tcIndex])
{
uTemp = (float)(u16)Memory_Read_U16(iAddress+2);
varray->SetV(tcIndex, uTemp * tcScaleV[tcIndex]);
}
tcIndex++;
}
void LOADERDECL TexCoord_ReadIndex16_Short(const void* _p)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]);
float uTemp;
uTemp = (float)(s16)Memory_Read_U16(iAddress );
varray->SetU(tcIndex, uTemp * tcScaleU[tcIndex]);
if (tcElements[tcIndex])
{
uTemp = (float)(s16)Memory_Read_U16(iAddress+2);
varray->SetV(tcIndex, uTemp * tcScaleV[tcIndex]);
}
tcIndex++;
}
void LOADERDECL TexCoord_ReadIndex16_Float(const void* _p)
{
u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]);
u32 uTemp;
uTemp = Memory_Read_U32(iAddress );
varray->SetU(tcIndex, *(float*)&uTemp * tcScaleU[tcIndex]);
if (tcElements[tcIndex])
{
uTemp = Memory_Read_U32(iAddress+4);
varray->SetV(tcIndex, *(float*)&uTemp * tcScaleV[tcIndex]);
}
tcIndex++;
}
#endif

View File

@ -23,28 +23,32 @@
#include "Profiler.h"
#include "VertexManager.h"
#include "OpcodeDecoding.h"
#include "TransformEngine.h"
#include "IndexGenerator.h"
#include "BPStructs.h"
#include "XFStructs.h"
#include "VertexShaderManager.h"
#include "VertexShaderCache.h"
#include "PixelShaderManager.h"
#include "PixelShaderCache.h"
#include "Utils.h"
#include "NativeVertexFormat.h"
#include "NativeVertexWriter.h"
#include "BPStructs.h"
#include "XFStructs.h"
using namespace D3D;
// internal state for loading vertices
extern NativeVertexFormat *g_nativeVertexFmt;
namespace VertexManager
{
enum Collection
{
C_NOTHING=0,
C_TRIANGLES=1,
C_LINES=2,
C_POINTS=3
C_NOTHING,
C_TRIANGLES,
C_LINES,
C_POINTS,
};
static IndexGenerator indexGen;
@ -52,29 +56,12 @@ static Collection collection;
static LPDIRECT3DVERTEXDECLARATION9 vDecl;
static D3DVertex *fakeVBuffer;
static u16 *fakeIBuffer;
static u8 *fakeVBuffer; // format undefined - NativeVertexFormat takes care of the declaration.
static u16 *fakeIBuffer; // These are just straightforward 16-bit indices.
#define MAXVBUFFERSIZE 65536*3
#define MAXIBUFFERSIZE 65536*3
const D3DVERTEXELEMENT9 decl[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
{ 0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
{ 0, 28, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1 },
{ 0, 32+12*0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
{ 0, 32+12*1, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
{ 0, 32+12*2, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2 },
{ 0, 32+12*3, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3 },
{ 0, 32+12*4, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4 },
{ 0, 32+12*5, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 5 },
{ 0, 32+12*6, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 6 },
{ 0, 32+12*7, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 7 },
D3DDECL_END()
};
const Collection collectionTypeLUT[8] =
{
C_TRIANGLES,//quads
@ -87,18 +74,16 @@ const Collection collectionTypeLUT[8] =
C_POINTS //guess :P
};
D3DVertex *vbufferwrite;
void CreateDeviceObjects();
void DestroyDeviceObjects();
bool Init()
{
collection = C_NOTHING;
fakeVBuffer = new D3DVertex[65536];
fakeIBuffer = new u16[65536];
fakeVBuffer = new u8[MAXVBUFFERSIZE];
fakeIBuffer = new u16[MAXIBUFFERSIZE];
CreateDeviceObjects();
VertexManager::s_pCurBufferPointer = fakeVBuffer;
return true;
}
@ -111,30 +96,20 @@ void Shutdown()
void CreateDeviceObjects()
{
HRESULT hr;
if (FAILED(hr = D3D::dev->CreateVertexDeclaration(decl, &vDecl)))
{
MessageBox(0,"Failed to create vertex declaration","sdfsd",0);
return;
}
}
void BeginFrame()
{
D3D::dev->SetVertexDeclaration(vDecl);
//D3D::dev->SetStreamSource(0,vBuffer,0,sizeof(D3DVertex));
}
void DestroyDeviceObjects()
{
if (vDecl)
vDecl->Release();
vDecl = 0;
}
void AddIndices(int _primitive, int _numVertices)
{
switch (_primitive) {
switch (_primitive)
{
case GX_DRAW_QUADS: indexGen.AddQuads(_numVertices); return;
case GX_DRAW_TRIANGLES: indexGen.AddList(_numVertices); return;
case GX_DRAW_TRIANGLE_STRIP: indexGen.AddStrip(_numVertices); return;
@ -145,7 +120,12 @@ void AddIndices(int _primitive, int _numVertices)
}
}
void AddVertices(int _primitive, int _numVertices, const DecodedVArray *varray)
int GetRemainingSize()
{
return 60000;
}
void AddVertices(int _primitive, int _numVertices)
{
if (_numVertices <= 0) //This check is pretty stupid...
return;
@ -168,32 +148,24 @@ void AddVertices(int _primitive, int _numVertices, const DecodedVArray *varray)
Flush();
collection = type;
u16 *ptr = 0;
if (type != C_POINTS)
{
ptr = fakeIBuffer;
indexGen.Start((unsigned short*)ptr);
AddIndices(_primitive,_numVertices);
AddIndices(_primitive, _numVertices);
}
vbufferwrite = fakeVBuffer;
if (_numVertices >= MAXVBUFFERSIZE)
MessageBox(NULL, "To much vertices for the buffer", "Video.DLL", MB_OK);
CTransformEngine::TransformVertices(_numVertices, varray, vbufferwrite);
MessageBox(NULL, "Too many vertices for the buffer", "Dolphin DX9 Video Plugin", MB_OK);
}
else //We are collecting the right type, keep going
{
_assert_msg_(vbufferwrite!=0, "collecting: vbufferwrite == 0!","WTF");
_assert_msg_(vbufferwrite != 0, "collecting: vbufferwrite == 0!","WTF");
INCSTAT(stats.thisFrame.numPrimitiveJoins);
//Success, keep adding to unlocked buffer
int last = indexGen.GetNumVerts();
AddIndices(_primitive, _numVertices);
if (_numVertices >= MAXVBUFFERSIZE)
MessageBox(NULL, "Too many vertices for the buffer", "Video.DLL", MB_OK);
CTransformEngine::TransformVertices(_numVertices, varray, vbufferwrite + last);
MessageBox(NULL, "Too many vertices for the buffer", "Dolphin DX9 Video Plugin", MB_OK);
}
}
@ -206,36 +178,44 @@ const D3DPRIMITIVETYPE pts[3] =
void Flush()
{
DVSTARTPROFILE();
if (collection != C_NOTHING)
DVSTARTPROFILE();
if (collection != C_NOTHING)
{
ActivateTextures();
int numVertices = indexGen.GetNumVerts();
if (numVertices != 0)
if (numVertices)
{
PShaderCache::SetShader(); // TODO(ector): only do this if shader has changed
VShaderCache::SetShader(); // TODO(ector): only do this if shader has changed
PixelShaderCache::SetShader(); // TODO(ector): only do this if shader has changed
VertexShaderCache::SetShader(g_nativeVertexFmt->m_components); // TODO(ector): only do this if shader has changed
// set global constants
VertexShaderManager::SetConstants(false, false);
PixelShaderManager::SetConstants();
int stride = g_nativeVertexFmt->GetVertexStride();
g_nativeVertexFmt->SetupVertexPointers();
if (collection != C_POINTS)
{
int numPrimitives = indexGen.GetNumPrims();
D3D::dev->DrawIndexedPrimitiveUP(pts[(int)collection],
0,
0,
numVertices,
numPrimitives,
fakeIBuffer,
D3DFMT_INDEX16,
fakeVBuffer,
sizeof(D3DVertex));
stride);
}
else
{
D3D::dev->SetIndices(0);
D3D::dev->DrawPrimitiveUP(D3DPT_POINTLIST, numVertices, fakeVBuffer, sizeof(D3DVertex));
D3D::dev->DrawPrimitiveUP(D3DPT_POINTLIST, numVertices, fakeVBuffer, stride);
}
INCSTAT(stats.thisFrame.numDrawCalls);
}
collection = C_NOTHING;
VertexManager::s_pCurBufferPointer = fakeVBuffer;
}
}

View File

@ -20,19 +20,6 @@
#include "CPMemory.h"
#include "VertexLoader.h"
#include "DecodedVArray.h"
struct UV
{
float u, v, w;
};
struct D3DVertex {
Vec3 pos;
Vec3 normal;
u32 colors[2];
UV uv[8];
};
namespace VertexManager
{
@ -42,7 +29,7 @@ void Shutdown();
void BeginFrame();
void AddVertices(int _primitive, int _numVertices, const DecodedVArray *varray);
void AddVertices(int _primitive, int _numVertices);
void Flush();
} // namespace

View File

@ -1,141 +0,0 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "stdafx.h"
#include "D3DShader.h"
#include "VertexShader.h"
#include "BPStructs.h"
static const char *genericVS = "// Generic Vertex Shader\
\n\
struct VS_INPUT {\n\
float4 pos : POSITION;\n\
float3 normal : NORMAL;\n\
float4 colors[2] : COLOR0;\n\
float4 uv[5] : TEXCOORD0;\n\
};\n\
\n\
struct VS_OUTPUT {\n\
float4 pos : POSITION;\n\
float4 colors[2] : COLOR0;\n\
//numtexgen\n\
float4 uv[5] : TEXCOORD0;\n\
};\n\
\n\
uniform matrix matWorldViewProj : register(c0);\n\
\n\
VS_OUTPUT main(const VS_INPUT input)\n\
{\n\
VS_OUTPUT output;\n\
\n\
output.pos = mul(input.pos, matWorldViewProj);\n\
// texgen\n\
for (int i=0; i<5; i++)\n output.uv[i] = input.uv[i];\n\
\n\
for (int i=0; i<2; i++)\n output.colors[i] = input.colors[i];\n\
return output;\n\
}\0";
const char *GenerateVertexShader() {
return genericVS;
}
/*
char text2[65536];
#define WRITE p+=sprintf
void WriteTexgen(char *&p, int n);
const char *GenerateVertexShader()
{
int numColors = 2;
int numUV = 8;
int numTexgen = bpmem.genMode.numtexgens;
int numNormals = 3;
bool fogEnable = false;
bool hasNormal = true;
char *p = text2;
WRITE(p,"//Vertex Shader\n");
WRITE(p,"//%i uv->%i texgens, %i colors\n",numUV,numTexgen,numColors);
WRITE(p,"\n");
WRITE(p,"struct VS_INPUT {\n");
WRITE(p," float4 pos : POSITION;\n");
WRITE(p," float3 normal : NORMAL;\n");
if (numColors)
WRITE(p," float4 colors[%i] : COLOR0;\n",numColors);
if (numUV)
WRITE(p," float3 uv[%i] : TEXCOORD0;\n",numUV);
WRITE(p,"};\n");
WRITE(p,"\n");
WRITE(p,"struct VS_OUTPUT {\n");
WRITE(p," float4 pos : POSITION;\n");
WRITE(p," float4 colors[%i] : COLOR0;\n",numColors);
if (numTexgen)
WRITE(p," float4 uv[%i] : TEXCOORD0;\n",numTexgen);
if (fogEnable)
WRITE(p," float fog : FOG;\n",numTexgen);
WRITE(p,"};\n");
WRITE(p,"\n");
WRITE(p,"uniform matrix matWorldViewProj : register(c0);\n");
WRITE(p,"\n");
WRITE(p,"VS_OUTPUT main(const VS_INPUT input)\n");
WRITE(p,"{\n");
WRITE(p," VS_OUTPUT output;");
WRITE(p,"\n");
WRITE(p," output.pos = mul(matWorldViewProj, input.pos);\n");
for (int i = 0; i < (int)bpmem.genMode.numtexgens; i++)
{
//build the equation for this stage
WriteTexgen(p,i);
}
WRITE(p," for (int i=0; i<2; i++)\n output.colors[i] = input.colors[i];\n");
//WRITE(p," output.fog = 0.0f;");
WRITE(p,"return output;\n");
WRITE(p,"}\n");
WRITE(p,"\0");
// MessageBox(0,text2,0,0);
return text2;
}
/*
* xform->vertexshader ideas
*//*
void WriteTexgen(char *&p, int n)
{
WRITE(p," output.uv[%i] = float4(input.uv[%i].xy,0,input.uv[%i].z);\n",n,n,n);
}
void WriteLight(int color, int component)
{
} */

View File

@ -1,50 +0,0 @@
// Copyright (C) 2003-2008 Dolphin 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.
// 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 SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _VERTEXSHADER_H
#define _VERTEXSHADER_H
#include "Common.h"
const char *GenerateVertexShader();
// shader variables
#define I_POSNORMALMATRIX "cpnmtx"
#define I_PROJECTION "cproj"
#define I_MATERIALS "cmtrl"
#define I_LIGHTS "clights"
#define I_TEXMATRICES "ctexmtx"
#define I_TRANSFORMMATRICES "ctrmtx"
#define I_NORMALMATRICES "cnmtx"
#define I_POSTTRANSFORMMATRICES "cpostmtx"
#define I_FOGPARAMS "cfog"
#define C_POSNORMALMATRIX 0
#define C_PROJECTION (C_POSNORMALMATRIX+6)
#define C_MATERIALS (C_PROJECTION+4)
#define C_LIGHTS (C_MATERIALS+4)
#define C_TEXMATRICES (C_LIGHTS+40)
#define C_TRANSFORMMATRICES (C_TEXMATRICES+24)
#define C_NORMALMATRICES (C_TRANSFORMMATRICES+64)
#define C_POSTTRANSFORMMATRICES (C_NORMALMATRICES+32)
#define C_FOGPARAMS (C_POSTTRANSFORMMATRICES+64)
#define PS_CONST_COLORS 0
#define PS_CONST_KCOLORS 4
#define PS_CONST_CONSTALPHA 8
#endif

View File

@ -18,6 +18,7 @@
#include <map>
#include "D3DBase.h"
#include "D3DShader.h"
#include "Statistics.h"
#include "Utils.h"
#include "Profiler.h"
@ -26,15 +27,27 @@
#include "BPMemory.h"
#include "XFMemory.h"
VShaderCache::VSCache VShaderCache::vshaders;
VertexShaderCache::VSCache VertexShaderCache::vshaders;
void VShaderCache::Init()
void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4)
{
const float f[4] = {f1, f2, f3, f4};
D3D::dev->SetVertexShaderConstantF(const_number, f, 1);
}
void SetVSConstant4fv(int const_number, const float *f)
{
D3D::dev->SetVertexShaderConstantF(const_number, f, 1);
}
void VertexShaderCache::Init()
{
}
void VShaderCache::Shutdown()
void VertexShaderCache::Shutdown()
{
VSCache::iterator iter = vshaders.begin();
for (; iter != vshaders.end(); iter++)
@ -43,28 +56,24 @@ void VShaderCache::Shutdown()
}
void VShaderCache::SetShader()
void VertexShaderCache::SetShader(u32 components)
{
static LPDIRECT3DVERTEXSHADER9 shader = NULL;
if (D3D::GetShaderVersion() < 2)
return; // we are screwed
if (shader) {
//D3D::dev->SetVertexShader(shader);
return;
}
static LPDIRECT3DVERTEXSHADER9 lastShader = 0;
DVSTARTPROFILE();
u32 currentHash = 0x1337; // GetCurrentTEV();
VERTEXSHADERUID uid;
GetVertexShaderId(uid, components, false);
VSCache::iterator iter;
iter = vshaders.find(currentHash);
iter = vshaders.find(uid);
if (iter != vshaders.end())
{
iter->second.frameCount=frameCount;
iter->second.frameCount = frameCount;
VSCacheEntry &entry = iter->second;
if (!lastShader || entry.shader != lastShader)
{
@ -74,15 +83,15 @@ void VShaderCache::SetShader()
return;
}
const char *code = GenerateVertexShader();
shader = D3D::CompileVShader(code, int(strlen(code)));
const char *code = GenerateVertexShader(components, false);
shader = D3D::CompileVertexShader(code, (int)strlen(code));
if (shader)
{
//Make an entry in the table
VSCacheEntry entry;
entry.shader = shader;
entry.frameCount=frameCount;
vshaders[currentHash] = entry;
entry.frameCount = frameCount;
vshaders[uid] = entry;
}
D3D::dev->SetVertexShader(shader);
@ -91,7 +100,7 @@ void VShaderCache::SetShader()
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
}
void VShaderCache::Cleanup()
void VertexShaderCache::Cleanup()
{
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end();)
{

View File

@ -22,10 +22,10 @@
#include <map>
#include "PixelShader.h"
#include "VertexShader.h"
#include "D3DBase.h"
#include "VertexShaderGen.h"
class VShaderCache
class VertexShaderCache
{
struct VSCacheEntry
{
@ -43,7 +43,7 @@ class VShaderCache
}
};
typedef std::map<u32, VSCacheEntry> VSCache;
typedef std::map<VERTEXSHADERUID, VSCacheEntry> VSCache;
static VSCache vshaders;
@ -51,7 +51,7 @@ public:
static void Init();
static void Cleanup();
static void Shutdown();
static void SetShader();
static void SetShader(u32 components);
};
#endif // _VERTEXSHADERCACHE_H

View File

@ -31,7 +31,6 @@
#include "BPStructs.h"
#include "VertexManager.h"
#include "VertexLoaderManager.h"
#include "TransformEngine.h"
#include "DlgSettings.h"
#include "D3DPostprocess.h"
#include "D3DTexture.h"

View File

@ -23,6 +23,4 @@
extern SVideoInitialize g_VideoInitialize;
void DebugLog(const char* _fmt, ...);
#endif

View File

@ -746,14 +746,6 @@
RelativePath=".\Src\VertexManager.h"
>
</File>
<File
RelativePath=".\Src\XFStructs.cpp"
>
</File>
<File
RelativePath=".\Src\XFStructs.h"
>
</File>
</Filter>
<Filter
Name="Render"

View File

@ -86,7 +86,6 @@ void BPWritten(int addr, int changes, int newval)
}
else if (glIsEnabled(GL_CULL_FACE) == GL_TRUE)
glDisable(GL_CULL_FACE);
PixelShaderManager::SetGenModeChanged();
}
break;
@ -177,7 +176,6 @@ void BPWritten(int addr, int changes, int newval)
case BPMEM_BLENDMODE:
if (changes & 0xFFFF) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
@ -343,23 +341,23 @@ void BPWritten(int addr, int changes, int newval)
{
case 0x02:
g_VideoInitialize.pSetPEFinish(); // may generate interrupt
DebugLog("GXSetDrawDone SetPEFinish (value: 0x%02X)", (newval & 0xFFFF));
DEBUG_LOG("GXSetDrawDone SetPEFinish (value: 0x%02X)", (newval & 0xFFFF));
break;
default:
DebugLog("GXSetDrawDone ??? (value 0x%02X)", (newval & 0xFFFF));
DEBUG_LOG("GXSetDrawDone ??? (value 0x%02X)", (newval & 0xFFFF));
break;
}
break;
case BPMEM_PE_TOKEN_ID:
g_VideoInitialize.pSetPEToken(static_cast<u16>(newval & 0xFFFF), FALSE);
DebugLog("SetPEToken 0x%04x", (newval & 0xFFFF));
DEBUG_LOG("SetPEToken 0x%04x", (newval & 0xFFFF));
break;
case BPMEM_PE_TOKEN_INT_ID:
g_VideoInitialize.pSetPEToken(static_cast<u16>(newval & 0xFFFF), TRUE);
DebugLog("SetPEToken + INT 0x%04x", (newval & 0xFFFF));
DEBUG_LOG("SetPEToken + INT 0x%04x", (newval & 0xFFFF));
break;
case BPMEM_SETGPMETRIC: // Set gp metric?
@ -558,6 +556,7 @@ void BPWritten(int addr, int changes, int newval)
}
break;
default:
switch (addr & 0xFC) //texture sampler filter
{
@ -649,7 +648,7 @@ void BPWritten(int addr, int changes, int newval)
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PixelShaderManager::SetTevIndirectChanged(addr-0x10);
PixelShaderManager::SetTevIndirectChanged(addr - 0x10);
}
break;
@ -657,7 +656,7 @@ void BPWritten(int addr, int changes, int newval)
if (changes) {
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PixelShaderManager::SetTexDimsChanged((addr>>1)&0x7);
PixelShaderManager::SetTexDimsChanged((addr >> 1) & 0x7);
}
break;
@ -667,7 +666,7 @@ void BPWritten(int addr, int changes, int newval)
{
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PixelShaderManager::SetTevCombinerChanged((addr&0x1f)/2);
PixelShaderManager::SetTevCombinerChanged((addr & 0x1f) / 2);
}
break;
@ -730,42 +729,3 @@ void BPWritten(int addr, int changes, int newval)
}
}
// Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg()
void LoadBPReg(u32 value0)
{
DVSTARTPROFILE();
// Handle the mask register
int opcode = value0 >> 24;
int oldval = ((u32*)&bpmem)[opcode];
int newval = (oldval & ~bpmem.bpMask) | (value0 & bpmem.bpMask);
// Check if it's a new value
int changes = (oldval ^ newval) & 0xFFFFFF;
//reset the mask register
if (opcode != 0xFE)
bpmem.bpMask = 0xFFFFFF;
// Notify the video handling so it can update render states
BPWritten(opcode, changes, newval);
}
// Called when loading a saved state.
// Needs more testing though.
void BPReload()
{
for (int i = 0; i < 254; i++)
{
switch (i) {
case 0x41:
case 0x45: //GXSetDrawDone
case 0x52:
case 0x65:
case 0x67: // set gp metric?
case BPMEM_PE_TOKEN_ID:
case BPMEM_PE_TOKEN_INT_ID:
// Cases in which we DON'T want to reload the BP
continue;
default:
BPWritten(i, 0xFFFFFF, ((u32*)&bpmem)[i]);
}
}
}

View File

@ -99,6 +99,7 @@ inline GLuint VarToGL(VarType t)
void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
{
vertex_stride = _vtx_decl.stride;
using namespace Gen;
if (_vtx_decl.stride & 3) {

View File

@ -137,7 +137,7 @@ void Flush()
_assert_(s_pCurBufferPointer != s_pBaseBufferPointer);
#if defined(_DEBUG) || defined(DEBUGFAST)
PRIM_LOG("frame%d:\ncomps=0x%x, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d\n", g_Config.iSaveTargetId, xfregs.numTexGens,
PRIM_LOG("frame%d:\n texgen=%d, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d\n", g_Config.iSaveTargetId, xfregs.numTexGens,
xfregs.nNumChans, (int)xfregs.bEnableDualTexTransform, bpmem.ztex2.op,
bpmem.blendmode.colorupdate, bpmem.blendmode.alphaupdate, bpmem.zmode.updateenable);
for (int i = 0; i < xfregs.nNumChans; ++i) {