| 
									
										
										
										
											2009-07-28 21:32:10 +00:00
										 |  |  | // Copyright (C) 2003 Dolphin Project.
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | // 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
 | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  |         if (address < XFMEM_ERROR) | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             VertexManager::Flush(); | 
					
						
							|  |  |  | 			VertexShaderManager::InvalidateXFRange(address, address + transferSize); | 
					
						
							|  |  |  |             //PRIM_LOG("xfmem write: 0x%x-0x%x\n", address, address+transferSize);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  |             memcpy_gc((u32*)&xfmem[address], &pData[i], transferSize*4); | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  |             i += transferSize; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  | 		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]; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-19 02:28:41 +00:00
										 |  |  | 		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; | 
					
						
							|  |  |  | 			}			 | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  |         else if (address < 0x2000) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             u32 data = pData[i]; | 
					
						
							|  |  |  |             switch (address) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  |             case XFMEM_ERROR: | 
					
						
							|  |  |  |             case XFMEM_DIAG: | 
					
						
							|  |  |  |             case XFMEM_STATE0: // internal state 0
 | 
					
						
							|  |  |  |             case XFMEM_STATE1: // internal state 1
 | 
					
						
							|  |  |  |             case XFMEM_CLOCK: | 
					
						
							|  |  |  | 			case XFMEM_SETGPMETRIC: | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             case XFMEM_CLIPDISABLE: | 
					
						
							|  |  |  | 				//if (data & 1) {} // disable clipping detection
 | 
					
						
							|  |  |  | 				//if (data & 2) {} // disable trivial rejection
 | 
					
						
							|  |  |  | 				//if (data & 4) {} // disable cpoly clipping acceleration
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             case XFMEM_VTXSPECS: //__GXXfVtxSpecs, wrote 0004
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  |                 xfregs.hostinfo = *(INVTXSPEC*)&data; | 
					
						
							|  |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             case XFMEM_SETNUMCHAN: | 
					
						
							|  |  |  | 				if ((u32)xfregs.nNumChans != (data & 3)) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  |                     VertexManager::Flush(); | 
					
						
							|  |  |  |                     xfregs.nNumChans = data & 3; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  |             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))  | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  |                     VertexManager::Flush(); | 
					
						
							|  |  |  |                     xfregs.bEnableDualTexTransform = data & 1; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             case XFMEM_SETMATRIXINDA: | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  |                 //_assert_msg_(GX_XF, 0, "XF matrixindex0");
 | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  | 				VertexShaderManager::SetTexMatrixChangedA(data); // ?
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  |             case XFMEM_SETMATRIXINDB: | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  |                 //_assert_msg_(GX_XF, 0, "XF matrixindex1");
 | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  |                 VertexShaderManager::SetTexMatrixChangedB(data); // ?
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  |             case XFMEM_SETNUMTEXGENS: // GXSetNumTexGens
 | 
					
						
							|  |  |  |                 if ((u32)xfregs.numTexGens != data) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  |                     VertexManager::Flush(); | 
					
						
							|  |  |  |                     xfregs.numTexGens = data; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2009-11-19 02:28:41 +00:00
										 |  |  |                 break;			 | 
					
						
							| 
									
										
										
										
											2009-08-24 04:04:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// --------------
 | 
					
						
							|  |  |  | 			// Unknown Regs
 | 
					
						
							|  |  |  | 			// --------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  | 			// Maybe these are for Normals?
 | 
					
						
							|  |  |  | 			case 0x1048: //xfregs.texcoords[0].nrmmtxinfo.hex = data; break; ??
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  |             case 0x1049: | 
					
						
							|  |  |  |             case 0x104a: | 
					
						
							|  |  |  |             case 0x104b: | 
					
						
							|  |  |  |             case 0x104c: | 
					
						
							|  |  |  |             case 0x104d: | 
					
						
							|  |  |  |             case 0x104e: | 
					
						
							|  |  |  |             case 0x104f: | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  | 				DEBUG_LOG(VIDEO, "Possible Normal Mtx XF reg?: %x=%x\n", address, data); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			case 0x1013: | 
					
						
							|  |  |  |             case 0x1014: | 
					
						
							|  |  |  |             case 0x1015: | 
					
						
							|  |  |  |             case 0x1016: | 
					
						
							|  |  |  |             case 0x1017: | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             default: | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  |                 WARN_LOG(VIDEO, "Unknown XF Reg: %x=%x\n", address, data); | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TODO - verify that it is correct. Seems to work, though.
 | 
					
						
							|  |  |  | void LoadIndexedXF(u32 val, int array) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int index = val >> 16; | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  |     int address = val & 0xFFF; // check mask
 | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  |     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++) | 
					
						
							| 
									
										
										
										
											2009-07-26 09:52:35 +00:00
										 |  |  |         xfmem[address + i] = Memory_Read_U32(arraybases[array] + arraystrides[array] * index + i * 4); | 
					
						
							| 
									
										
										
										
											2009-03-07 08:35:01 +00:00
										 |  |  | } |