mirror of
				https://github.com/dolphin-emu/dolphin.git
				synced 2025-10-27 10:29:07 +00:00 
			
		
		
		
	git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4589 8ced0084-cf51-0410-be5f-012b33b47a6e
		
			
				
	
	
		
			224 lines
		
	
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			224 lines
		
	
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright (C) 2003 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"
 | |
| #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 < XFMEM_ERROR)
 | |
|         {
 | |
|             VertexManager::Flush();
 | |
| 			VertexShaderManager::InvalidateXFRange(address, address + transferSize);
 | |
|             //PRIM_LOG("xfmem write: 0x%x-0x%x\n", address, address+transferSize);
 | |
| 
 | |
|             memcpy_gc((u32*)&xfmem[address], &pData[i], transferSize*4);
 | |
|             i += transferSize;
 | |
|         }
 | |
| 		else if (address >= XFMEM_SETTEXMTXINFO && address <= XFMEM_SETTEXMTXINFO+7)
 | |
| 		{
 | |
| 			xfregs.texcoords[address - XFMEM_SETTEXMTXINFO].texmtxinfo.hex = pData[i];
 | |
| 		}
 | |
| 		else if (address >= XFMEM_SETPOSMTXINFO && address <= XFMEM_SETPOSMTXINFO+7)
 | |
| 		{
 | |
| 			xfregs.texcoords[address - XFMEM_SETPOSMTXINFO].postmtxinfo.hex = pData[i];
 | |
| 		}
 | |
| 		else if (address >= XFMEM_SETVIEWPORT && address <= XFMEM_SETVIEWPORT+5)
 | |
| 		{
 | |
| 			VertexManager::Flush();
 | |
| 			u32 Index = address - XFMEM_SETVIEWPORT;
 | |
|             VertexShaderManager::SetViewport((float*)&pData[i],Index);
 | |
| 			PixelShaderManager::SetViewport((float*)&pData[i],Index);
 | |
|             if(Index == 0)
 | |
| 			{
 | |
| 				i += 5;
 | |
| 			}
 | |
| 
 | |
| 		}
 | |
| 		else if (address >= XFMEM_SETPROJECTION && address <= XFMEM_SETPROJECTION+7)
 | |
| 		{
 | |
| 			VertexManager::Flush();
 | |
| 			u32 Index = address - XFMEM_SETPROJECTION;
 | |
|             VertexShaderManager::SetProjection((float*)&pData[i],Index);
 | |
| 			if(Index == 0)
 | |
| 			{
 | |
| 				i += 7;
 | |
| 			}			
 | |
| 		}
 | |
|         else if (address < 0x2000)
 | |
|         {
 | |
|             u32 data = pData[i];
 | |
|             switch (address)
 | |
|             {
 | |
|             case XFMEM_ERROR:
 | |
|             case XFMEM_DIAG:
 | |
|             case XFMEM_STATE0: // internal state 0
 | |
|             case XFMEM_STATE1: // internal state 1
 | |
|             case XFMEM_CLOCK:
 | |
| 			case XFMEM_SETGPMETRIC:
 | |
|                 break;
 | |
| 
 | |
|             case XFMEM_CLIPDISABLE:
 | |
| 				//if (data & 1) {} // disable clipping detection
 | |
| 				//if (data & 2) {} // disable trivial rejection
 | |
| 				//if (data & 4) {} // disable cpoly clipping acceleration
 | |
|                 break;
 | |
| 
 | |
|             case XFMEM_VTXSPECS: //__GXXfVtxSpecs, wrote 0004
 | |
|                 xfregs.hostinfo = *(INVTXSPEC*)&data;
 | |
|                 break;
 | |
| 
 | |
|             case XFMEM_SETNUMCHAN:
 | |
| 				if ((u32)xfregs.nNumChans != (data & 3))
 | |
| 				{
 | |
|                     VertexManager::Flush();
 | |
|                     xfregs.nNumChans = data & 3;
 | |
|                 }
 | |
|                 break;
 | |
| 
 | |
|             case XFMEM_SETCHAN0_AMBCOLOR: // Channel Ambient Color
 | |
| 			case XFMEM_SETCHAN1_AMBCOLOR:
 | |
| 				{
 | |
| 					u8 chan = address - XFMEM_SETCHAN0_AMBCOLOR;
 | |
| 					if (xfregs.colChans[chan].ambColor != data) 
 | |
| 					{
 | |
| 						VertexManager::Flush();
 | |
| 						xfregs.colChans[chan].ambColor = data;
 | |
| 						VertexShaderManager::SetMaterialColor(chan, data);
 | |
| 					}
 | |
| 					break;
 | |
| 				}
 | |
| 
 | |
|             case XFMEM_SETCHAN0_MATCOLOR: // Channel Material Color
 | |
| 			case XFMEM_SETCHAN1_MATCOLOR:
 | |
| 				{
 | |
| 					u8 chan = address - XFMEM_SETCHAN0_MATCOLOR;
 | |
| 					if (xfregs.colChans[chan].matColor != data)
 | |
| 					{
 | |
| 						VertexManager::Flush();
 | |
| 						xfregs.colChans[chan].matColor = data;
 | |
| 						VertexShaderManager::SetMaterialColor(address - XFMEM_SETCHAN0_AMBCOLOR, data);
 | |
| 					}
 | |
| 					break;
 | |
| 				}
 | |
| 
 | |
|             case XFMEM_SETCHAN0_COLOR: // Channel Color
 | |
| 			case XFMEM_SETCHAN1_COLOR:
 | |
| 				{
 | |
| 					u8 chan = address - XFMEM_SETCHAN0_COLOR;
 | |
| 					if (xfregs.colChans[chan].color.hex != (data & 0x7fff))
 | |
| 					{
 | |
| 						VertexManager::Flush();
 | |
| 						xfregs.colChans[chan].color.hex = data;
 | |
| 					}
 | |
| 					break;
 | |
| 				}
 | |
| 
 | |
|             case XFMEM_SETCHAN0_ALPHA: // Channel Alpha
 | |
| 			case XFMEM_SETCHAN1_ALPHA:
 | |
| 				{
 | |
| 					u8 chan = address - XFMEM_SETCHAN0_ALPHA;
 | |
| 					if (xfregs.colChans[chan].alpha.hex != (data & 0x7fff))
 | |
| 					{
 | |
| 						VertexManager::Flush();
 | |
| 						xfregs.colChans[chan].alpha.hex = data;
 | |
| 					}
 | |
| 					break;
 | |
| 				}
 | |
| 
 | |
|             case XFMEM_DUALTEX:
 | |
|                 if (xfregs.bEnableDualTexTransform != (data & 1)) 
 | |
| 				{
 | |
|                     VertexManager::Flush();
 | |
|                     xfregs.bEnableDualTexTransform = data & 1;
 | |
|                 }
 | |
|                 break;
 | |
| 
 | |
| 
 | |
|             case XFMEM_SETMATRIXINDA:
 | |
|                 //_assert_msg_(GX_XF, 0, "XF matrixindex0");
 | |
| 				VertexShaderManager::SetTexMatrixChangedA(data); // ?
 | |
|                 break;
 | |
|             case XFMEM_SETMATRIXINDB:
 | |
|                 //_assert_msg_(GX_XF, 0, "XF matrixindex1");
 | |
|                 VertexShaderManager::SetTexMatrixChangedB(data); // ?
 | |
|                 break;
 | |
|             case XFMEM_SETNUMTEXGENS: // GXSetNumTexGens
 | |
|                 if ((u32)xfregs.numTexGens != data)
 | |
| 				{
 | |
|                     VertexManager::Flush();
 | |
|                     xfregs.numTexGens = data;
 | |
|                 }
 | |
|                 break;			
 | |
| 
 | |
| 			// --------------
 | |
| 			// Unknown Regs
 | |
| 			// --------------
 | |
| 
 | |
| 			// Maybe these are for Normals?
 | |
| 			case 0x1048: //xfregs.texcoords[0].nrmmtxinfo.hex = data; break; ??
 | |
|             case 0x1049:
 | |
|             case 0x104a:
 | |
|             case 0x104b:
 | |
|             case 0x104c:
 | |
|             case 0x104d:
 | |
|             case 0x104e:
 | |
|             case 0x104f:
 | |
| 				DEBUG_LOG(VIDEO, "Possible Normal Mtx XF reg?: %x=%x\n", address, data);
 | |
| 				break;
 | |
| 
 | |
| 			case 0x1013:
 | |
|             case 0x1014:
 | |
|             case 0x1015:
 | |
|             case 0x1016:
 | |
|             case 0x1017:
 | |
| 
 | |
|             default:
 | |
|                 WARN_LOG(VIDEO, "Unknown XF Reg: %x=%x\n", address, data);
 | |
|                 break;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| // 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);
 | |
| }
 |