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:
parent
ee44b2a639
commit
ecbfec2a13
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -1,236 +1,233 @@
|
|||
// 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 "Common.h"
|
||||
#include "Globals.h"
|
||||
#include "XFMemory.h"
|
||||
#include "VertexManager.h"
|
||||
#include "VertexShaderManager.h"
|
||||
#include "PixelShaderManager.h"
|
||||
|
||||
// LoadXFReg 0x10
|
||||
void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
|
||||
{
|
||||
u32 address = baseAddress;
|
||||
for (int i = 0; i < (int)transferSize; i++)
|
||||
{
|
||||
address = baseAddress + i;
|
||||
|
||||
// Setup a Matrix
|
||||
if (address < 0x1000)
|
||||
{
|
||||
VertexManager::Flush();
|
||||
VertexShaderManager::InvalidateXFRange(address, address + transferSize);
|
||||
//PRIM_LOG("xfmem write: 0x%x-0x%x\n", address, address+transferSize);
|
||||
|
||||
u32* p1 = &xfmem[address];
|
||||
memcpy_gc(p1, &pData[i], transferSize*4);
|
||||
i += transferSize;
|
||||
}
|
||||
else if (address<0x2000)
|
||||
{
|
||||
u32 data = pData[i];
|
||||
switch (address)
|
||||
{
|
||||
case 0x1000: // error
|
||||
break;
|
||||
case 0x1001: // diagnostics
|
||||
break;
|
||||
case 0x1002: // internal state 0
|
||||
break;
|
||||
case 0x1003: // internal state 1
|
||||
break;
|
||||
case 0x1004: // xf_clock
|
||||
break;
|
||||
case 0x1005: // clipdisable
|
||||
if (data & 1) { // disable clipping detection
|
||||
}
|
||||
if (data & 2) { // disable trivial rejection
|
||||
}
|
||||
if (data & 4) { // disable cpoly clipping acceleration
|
||||
}
|
||||
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)) {
|
||||
VertexManager::Flush();
|
||||
xfregs.nNumChans = data&3;
|
||||
}
|
||||
break;
|
||||
case 0x100a: //GXSetChanAmbientcolor
|
||||
if (xfregs.colChans[0].ambColor != data) {
|
||||
VertexManager::Flush();
|
||||
xfregs.colChans[0].ambColor = data;
|
||||
VertexShaderManager::SetMaterialColor(0, data);
|
||||
}
|
||||
break;
|
||||
case 0x100b: //GXSetChanAmbientcolor
|
||||
if (xfregs.colChans[1].ambColor != data) {
|
||||
VertexManager::Flush();
|
||||
xfregs.colChans[1].ambColor = data;
|
||||
VertexShaderManager::SetMaterialColor(1, data);
|
||||
}
|
||||
break;
|
||||
case 0x100c: //GXSetChanMatcolor (rgba)
|
||||
if (xfregs.colChans[0].matColor != data) {
|
||||
VertexManager::Flush();
|
||||
xfregs.colChans[0].matColor = data;
|
||||
VertexShaderManager::SetMaterialColor(2, data);
|
||||
}
|
||||
break;
|
||||
case 0x100d: //GXSetChanMatcolor (rgba)
|
||||
if (xfregs.colChans[1].matColor != data) {
|
||||
VertexManager::Flush();
|
||||
xfregs.colChans[1].matColor = data;
|
||||
VertexShaderManager::SetMaterialColor(3, data);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x100e: // color0
|
||||
if (xfregs.colChans[0].color.hex != (data & 0x7fff) ) {
|
||||
VertexManager::Flush();
|
||||
xfregs.colChans[0].color.hex = data;
|
||||
}
|
||||
break;
|
||||
case 0x100f: // color1
|
||||
if (xfregs.colChans[1].color.hex != (data & 0x7fff) ) {
|
||||
VertexManager::Flush();
|
||||
xfregs.colChans[1].color.hex = data;
|
||||
}
|
||||
break;
|
||||
case 0x1010: // alpha0
|
||||
if (xfregs.colChans[0].alpha.hex != (data & 0x7fff) ) {
|
||||
VertexManager::Flush();
|
||||
xfregs.colChans[0].alpha.hex = data;
|
||||
}
|
||||
break;
|
||||
case 0x1011: // alpha1
|
||||
if (xfregs.colChans[1].alpha.hex != (data & 0x7fff) ) {
|
||||
VertexManager::Flush();
|
||||
xfregs.colChans[1].alpha.hex = data;
|
||||
}
|
||||
break;
|
||||
case 0x1012: // dual tex transform
|
||||
if (xfregs.bEnableDualTexTransform != (data & 1)) {
|
||||
VertexManager::Flush();
|
||||
xfregs.bEnableDualTexTransform = data & 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1013:
|
||||
case 0x1014:
|
||||
case 0x1015:
|
||||
case 0x1016:
|
||||
case 0x1017:
|
||||
DEBUG_LOG(VIDEO, "xf addr: %x=%x\n", address, data);
|
||||
break;
|
||||
case 0x1018:
|
||||
//_assert_msg_(GX_XF, 0, "XF matrixindex0");
|
||||
VertexShaderManager::SetTexMatrixChangedA(data); //?
|
||||
break;
|
||||
case 0x1019:
|
||||
//_assert_msg_(GX_XF, 0, "XF matrixindex1");
|
||||
VertexShaderManager::SetTexMatrixChangedB(data); //?
|
||||
break;
|
||||
|
||||
case 0x101a:
|
||||
VertexManager::Flush();
|
||||
VertexShaderManager::SetViewport((float*)&pData[i]);
|
||||
PixelShaderManager::SetViewport((float*)&pData[i]);
|
||||
i += 6;
|
||||
break;
|
||||
|
||||
case 0x101c: // paper mario writes 16777216.0f, 1677721.75
|
||||
break;
|
||||
case 0x101f: // paper mario writes 16777216.0f, 5033165.0f
|
||||
break;
|
||||
|
||||
case 0x1020:
|
||||
VertexManager::Flush();
|
||||
VertexShaderManager::SetProjection((float*)&pData[i]);
|
||||
i += 7;
|
||||
return;
|
||||
|
||||
case 0x103f: // GXSetNumTexGens
|
||||
if ((u32)xfregs.numTexGens != data) {
|
||||
VertexManager::Flush();
|
||||
xfregs.numTexGens = data;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1040: xfregs.texcoords[0].texmtxinfo.hex = data; break;
|
||||
case 0x1041: xfregs.texcoords[1].texmtxinfo.hex = data; break;
|
||||
case 0x1042: xfregs.texcoords[2].texmtxinfo.hex = data; break;
|
||||
case 0x1043: xfregs.texcoords[3].texmtxinfo.hex = data; break;
|
||||
case 0x1044: xfregs.texcoords[4].texmtxinfo.hex = data; break;
|
||||
case 0x1045: xfregs.texcoords[5].texmtxinfo.hex = data; break;
|
||||
case 0x1046: xfregs.texcoords[6].texmtxinfo.hex = data; break;
|
||||
case 0x1047: xfregs.texcoords[7].texmtxinfo.hex = data; break;
|
||||
|
||||
case 0x1048:
|
||||
case 0x1049:
|
||||
case 0x104a:
|
||||
case 0x104b:
|
||||
case 0x104c:
|
||||
case 0x104d:
|
||||
case 0x104e:
|
||||
case 0x104f:
|
||||
DEBUG_LOG(VIDEO, "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;
|
||||
case 0x1052: xfregs.texcoords[2].postmtxinfo.hex = data; break;
|
||||
case 0x1053: xfregs.texcoords[3].postmtxinfo.hex = data; break;
|
||||
case 0x1054: xfregs.texcoords[4].postmtxinfo.hex = data; break;
|
||||
case 0x1055: xfregs.texcoords[5].postmtxinfo.hex = data; break;
|
||||
case 0x1056: xfregs.texcoords[6].postmtxinfo.hex = data; break;
|
||||
case 0x1057: xfregs.texcoords[7].postmtxinfo.hex = data; break;
|
||||
|
||||
default:
|
||||
DEBUG_LOG(VIDEO, "xf addr: %x=%x\n", address, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (address >= 0x4000)
|
||||
{
|
||||
// MessageBox(NULL, "1", "1", MB_OK);
|
||||
//4010 __GXSetGenMode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO - verify that it is correct. Seems to work, though.
|
||||
void LoadIndexedXF(u32 val, int array)
|
||||
{
|
||||
int index = val >> 16;
|
||||
int address = val & 0xFFF; //check mask
|
||||
int size = ((val >> 12) & 0xF) + 1;
|
||||
//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);
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
xfmem[address + i] = Memory_Read_U32(arraybases[array] + arraystrides[array] * index + i * 4);
|
||||
}
|
||||
// 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 "Common.h"
|
||||
#include "VideoCommon.h"
|
||||
#include "XFMemory.h"
|
||||
#include "CPMemory.h"
|
||||
#include "NativeVertexWriter.h"
|
||||
#include "VertexShaderManager.h"
|
||||
|
||||
// LoadXFReg 0x10
|
||||
void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
|
||||
{
|
||||
u32 address = baseAddress;
|
||||
for (int i = 0; i < (int)transferSize; i++)
|
||||
{
|
||||
address = baseAddress + i;
|
||||
|
||||
// Setup a Matrix
|
||||
if (address < 0x1000)
|
||||
{
|
||||
VertexManager::Flush();
|
||||
VertexShaderManager::InvalidateXFRange(address, address + transferSize);
|
||||
//PRIM_LOG("xfmem write: 0x%x-0x%x\n", address, address+transferSize);
|
||||
|
||||
u32* p1 = &xfmem[address];
|
||||
memcpy_gc(p1, &pData[i], transferSize*4);
|
||||
i += transferSize;
|
||||
}
|
||||
else if (address < 0x2000)
|
||||
{
|
||||
u32 data = pData[i];
|
||||
switch (address)
|
||||
{
|
||||
case 0x1000: // error
|
||||
break;
|
||||
case 0x1001: // diagnostics
|
||||
break;
|
||||
case 0x1002: // internal state 0
|
||||
break;
|
||||
case 0x1003: // internal state 1
|
||||
break;
|
||||
case 0x1004: // xf_clock
|
||||
break;
|
||||
case 0x1005: // clipdisable
|
||||
if (data & 1) { // disable clipping detection
|
||||
}
|
||||
if (data & 2) { // disable trivial rejection
|
||||
}
|
||||
if (data & 4) { // disable cpoly clipping acceleration
|
||||
}
|
||||
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)) {
|
||||
VertexManager::Flush();
|
||||
xfregs.nNumChans = data & 3;
|
||||
}
|
||||
break;
|
||||
case 0x100a: //GXSetChanAmbientcolor
|
||||
if (xfregs.colChans[0].ambColor != data) {
|
||||
VertexManager::Flush();
|
||||
xfregs.colChans[0].ambColor = data;
|
||||
VertexShaderManager::SetMaterialColor(0, data);
|
||||
}
|
||||
break;
|
||||
case 0x100b: //GXSetChanAmbientcolor
|
||||
if (xfregs.colChans[1].ambColor != data) {
|
||||
VertexManager::Flush();
|
||||
xfregs.colChans[1].ambColor = data;
|
||||
VertexShaderManager::SetMaterialColor(1, data);
|
||||
}
|
||||
break;
|
||||
case 0x100c: //GXSetChanMatcolor (rgba)
|
||||
if (xfregs.colChans[0].matColor != data) {
|
||||
VertexManager::Flush();
|
||||
xfregs.colChans[0].matColor = data;
|
||||
VertexShaderManager::SetMaterialColor(2, data);
|
||||
}
|
||||
break;
|
||||
case 0x100d: //GXSetChanMatcolor (rgba)
|
||||
if (xfregs.colChans[1].matColor != data) {
|
||||
VertexManager::Flush();
|
||||
xfregs.colChans[1].matColor = data;
|
||||
VertexShaderManager::SetMaterialColor(3, data);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x100e: // color0
|
||||
if (xfregs.colChans[0].color.hex != (data & 0x7fff) ) {
|
||||
VertexManager::Flush();
|
||||
xfregs.colChans[0].color.hex = data;
|
||||
}
|
||||
break;
|
||||
case 0x100f: // color1
|
||||
if (xfregs.colChans[1].color.hex != (data & 0x7fff) ) {
|
||||
VertexManager::Flush();
|
||||
xfregs.colChans[1].color.hex = data;
|
||||
}
|
||||
break;
|
||||
case 0x1010: // alpha0
|
||||
if (xfregs.colChans[0].alpha.hex != (data & 0x7fff) ) {
|
||||
VertexManager::Flush();
|
||||
xfregs.colChans[0].alpha.hex = data;
|
||||
}
|
||||
break;
|
||||
case 0x1011: // alpha1
|
||||
if (xfregs.colChans[1].alpha.hex != (data & 0x7fff) ) {
|
||||
VertexManager::Flush();
|
||||
xfregs.colChans[1].alpha.hex = data;
|
||||
}
|
||||
break;
|
||||
case 0x1012: // dual tex transform
|
||||
if (xfregs.bEnableDualTexTransform != (data & 1)) {
|
||||
VertexManager::Flush();
|
||||
xfregs.bEnableDualTexTransform = data & 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1013:
|
||||
case 0x1014:
|
||||
case 0x1015:
|
||||
case 0x1016:
|
||||
case 0x1017:
|
||||
DEBUG_LOG("xf addr: %x=%x\n", address, data);
|
||||
break;
|
||||
case 0x1018:
|
||||
//_assert_msg_(GX_XF, 0, "XF matrixindex0");
|
||||
VertexShaderManager::SetTexMatrixChangedA(data); //?
|
||||
break;
|
||||
case 0x1019:
|
||||
//_assert_msg_(GX_XF, 0, "XF matrixindex1");
|
||||
VertexShaderManager::SetTexMatrixChangedB(data); //?
|
||||
break;
|
||||
|
||||
case 0x101a:
|
||||
VertexManager::Flush();
|
||||
VertexShaderManager::SetViewport((float*)&pData[i]);
|
||||
i += 6;
|
||||
break;
|
||||
|
||||
case 0x101c: // paper mario writes 16777216.0f, 1677721.75
|
||||
break;
|
||||
case 0x101f: // paper mario writes 16777216.0f, 5033165.0f
|
||||
break;
|
||||
|
||||
case 0x1020:
|
||||
VertexManager::Flush();
|
||||
VertexShaderManager::SetProjection((float*)&pData[i]);
|
||||
i += 7;
|
||||
return;
|
||||
|
||||
case 0x103f: // GXSetNumTexGens
|
||||
if ((u32)xfregs.numTexGens != data) {
|
||||
VertexManager::Flush();
|
||||
xfregs.numTexGens = data;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1040: xfregs.texcoords[0].texmtxinfo.hex = data; break;
|
||||
case 0x1041: xfregs.texcoords[1].texmtxinfo.hex = data; break;
|
||||
case 0x1042: xfregs.texcoords[2].texmtxinfo.hex = data; break;
|
||||
case 0x1043: xfregs.texcoords[3].texmtxinfo.hex = data; break;
|
||||
case 0x1044: xfregs.texcoords[4].texmtxinfo.hex = data; break;
|
||||
case 0x1045: xfregs.texcoords[5].texmtxinfo.hex = data; break;
|
||||
case 0x1046: xfregs.texcoords[6].texmtxinfo.hex = data; break;
|
||||
case 0x1047: xfregs.texcoords[7].texmtxinfo.hex = data; break;
|
||||
|
||||
case 0x1048:
|
||||
case 0x1049:
|
||||
case 0x104a:
|
||||
case 0x104b:
|
||||
case 0x104c:
|
||||
case 0x104d:
|
||||
case 0x104e:
|
||||
case 0x104f:
|
||||
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;
|
||||
case 0x1052: xfregs.texcoords[2].postmtxinfo.hex = data; break;
|
||||
case 0x1053: xfregs.texcoords[3].postmtxinfo.hex = data; break;
|
||||
case 0x1054: xfregs.texcoords[4].postmtxinfo.hex = data; break;
|
||||
case 0x1055: xfregs.texcoords[5].postmtxinfo.hex = data; break;
|
||||
case 0x1056: xfregs.texcoords[6].postmtxinfo.hex = data; break;
|
||||
case 0x1057: xfregs.texcoords[7].postmtxinfo.hex = data; break;
|
||||
|
||||
default:
|
||||
DEBUG_LOG("xf addr: %x=%x\n", address, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (address >= 0x4000)
|
||||
{
|
||||
// MessageBox(NULL, "1", "1", MB_OK);
|
||||
//4010 __GXSetGenMode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO - verify that it is correct. Seems to work, though.
|
||||
void LoadIndexedXF(u32 val, int array)
|
||||
{
|
||||
int index = val >> 16;
|
||||
int address = val & 0xFFF; //check mask
|
||||
int size = ((val >> 12) & 0xF) + 1;
|
||||
//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);
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
xfmem[address + i] = Memory_Read_U32(arraybases[array] + arraystrides[array]*index + i*4);
|
||||
}
|
|
@ -1,18 +1,18 @@
|
|||
// 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 "XFMemory.h"
|
||||
// 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 "XFMemory.h"
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
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_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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
}
|
|
@ -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
|
|
@ -52,6 +52,7 @@ namespace EmuWindow
|
|||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
exit(0);
|
||||
return 0;
|
||||
|
||||
case WM_DESTROY:
|
||||
|
|
|
@ -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!");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
|
@ -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());
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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__
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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]))();
|
||||
}*/
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
};
|
|
@ -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
|
|
@ -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
|
|
@ -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,37 +178,45 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
||||
} */
|
|
@ -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
|
|
@ -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();)
|
||||
{
|
||||
|
@ -107,4 +116,4 @@ void VShaderCache::Cleanup()
|
|||
}
|
||||
}
|
||||
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -23,6 +23,4 @@
|
|||
|
||||
extern SVideoInitialize g_VideoInitialize;
|
||||
|
||||
void DebugLog(const char* _fmt, ...);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -320,7 +318,7 @@ void BPWritten(int addr, int changes, int newval)
|
|||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 0xf6: // ksel0
|
||||
case 0xf7: // ksel1
|
||||
case 0xf8: // ksel2
|
||||
|
@ -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?
|
||||
|
@ -557,6 +555,7 @@ void BPWritten(int addr, int changes, int newval)
|
|||
// Not sure if it's a good idea, though. For now, we hash texture palettes
|
||||
}
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue