2013-04-17 23:29:41 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// Copyright 2013 Dolphin Emulator Project
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Licensed under GPLv2
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Refer to the license.txt file included.
 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-07-29 20:55:07 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "Common/ChunkFile.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2014-09-07 20:06:58 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "Common/CommonTypes.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-17 05:18:15 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "Core/HW/Memmap.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "VideoBackends/Software/BPMemLoader.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "VideoBackends/Software/CPMemLoader.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "VideoBackends/Software/DebugUtil.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "VideoBackends/Software/OpcodeDecoder.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "VideoBackends/Software/SWCommandProcessor.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "VideoBackends/Software/SWStatistics.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "VideoBackends/Software/SWVertexLoader.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "VideoBackends/Software/SWVideoConfig.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "VideoBackends/Software/XFMemLoader.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "VideoCommon/DataReader.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2014-07-08 16:49:33 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "VideoCommon/Fifo.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								typedef  void  ( * DecodingFunction ) ( u32 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								namespace  OpcodeDecoder 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-09 21:14:26 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  DecodingFunction  currentFunction  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-16 22:48:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  u32  minCommandSize ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  u16  streamSize ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  u16  streamAddress ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  bool  readOpcode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  SWVertexLoader  vertexLoader ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  bool  inObjectStream ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  u8  lastPrimCmd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-02-25 20:05:02 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  DoState ( PointerWrap  & p ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									p . Do ( minCommandSize ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-25 23:49:24 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// Not sure what is wrong with this. Something(s) in here is causing dolphin to crash/hang when loading states saved from another run of dolphin. Doesn't seem too important anyway...
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									//vertexLoader.DoState(p);
 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-25 20:05:02 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									p . Do ( readOpcode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									p . Do ( inObjectStream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									p . Do ( lastPrimCmd ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-25 23:49:24 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									p . Do ( streamSize ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									p . Do ( streamAddress ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-26 18:43:37 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( p . GetMode ( )  = =  PointerWrap : : MODE_READ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										  ResetDecoding ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-25 20:05:02 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-07-08 14:29:26 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  DecodePrimitiveStream ( u32  iBufferSize ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									u32  vertexSize  =  vertexLoader . GetVertexSize ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-29 08:34:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									bool  skipPrimitives  =  g_bSkipCurrentFrame  | | 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-03 19:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										 swstats . thisFrame . numDrawnObjects  <  g_SWVideoConfig . drawStart  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 swstats . thisFrame . numDrawnObjects  > =  g_SWVideoConfig . drawEnd ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-29 08:34:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( skipPrimitives ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										while  ( streamSize  >  0  & &  iBufferSize  > =  vertexSize ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2014-08-26 13:37:32 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											g_video_buffer_read_ptr  + =  vertexSize ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											iBufferSize  - =  vertexSize ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											streamSize - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										while  ( streamSize  >  0  & &  iBufferSize  > =  vertexSize ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											vertexLoader . LoadVertex ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											iBufferSize  - =  vertexSize ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											streamSize - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( streamSize  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// return to normal command processing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ResetDecoding ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-07-08 14:29:26 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  ReadXFData ( u32  iBufferSize ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2013-10-29 01:23:17 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									_assert_msg_ ( VIDEO ,  iBufferSize  > =  ( u32 ) ( streamSize  *  4 ) ,  " Underflow during standard opcode decoding " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									u32  pData [ 16 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( int  i  =  0 ;  i  <  streamSize ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pData [ i ]  =  DataReadU32 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									SWLoadXFReg ( streamSize ,  streamAddress ,  pData ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// return to normal command processing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ResetDecoding ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-07-08 14:29:26 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  ExecuteDisplayList ( u32  addr ,  u32  count ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2014-08-26 13:37:32 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									u8  * videoDataSave  =  g_video_buffer_read_ptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									u8  * dlStart  =  Memory : : GetPointer ( addr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-08-26 13:37:32 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									g_video_buffer_read_ptr  =  dlStart ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									while  ( OpcodeDecoder : : CommandRunnable ( count ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										OpcodeDecoder : : Run ( count ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										// if data was read by the opcode decoder then the video data pointer changed
 
							 
						 
					
						
							
								
									
										
										
										
											2014-08-26 13:37:32 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										u32  readCount  =  ( u32 ) ( g_video_buffer_read_ptr  -  dlStart ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										dlStart  =  g_video_buffer_read_ptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-10-29 01:23:17 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										_assert_msg_ ( VIDEO ,  count  > =  readCount ,  " Display list underrun " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										count  - =  readCount ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-08-26 13:37:32 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									g_video_buffer_read_ptr  =  videoDataSave ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-07-08 14:29:26 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  DecodeStandard ( u32  bufferSize ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2013-10-29 01:23:17 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									_assert_msg_ ( VIDEO ,  CommandRunnable ( bufferSize ) ,  " Underflow during standard opcode decoding " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  Cmd  =  DataReadU8 ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( Cmd  = =  GX_NOP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Causes a SIGBUS error on Android
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// XXX: Investigate
 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-26 13:49:00 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifndef ANDROID 
 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// check if switching in or out of an object
 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-19 09:21:45 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// only used for debugging
 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( inObjectStream  & &  ( Cmd  &  0x87 )  ! =  lastPrimCmd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										inObjectStream  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										DebugUtil : : OnObjectEnd ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( Cmd  &  0x80  & &  ! inObjectStream ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										inObjectStream  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										lastPrimCmd  =  Cmd  &  0x87 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										DebugUtil : : OnObjectBegin ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-26 13:49:00 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2014-03-11 00:30:55 +13:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									switch  ( Cmd ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  GX_NOP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  GX_LOAD_CP_REG :  //0x08
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											u32  SubCmd  =  DataReadU8 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											u32  Value  =  DataReadU32 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											SWLoadCPReg ( SubCmd ,  Value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  GX_LOAD_XF_REG : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											u32  Cmd2  =  DataReadU32 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											streamSize  =  ( ( Cmd2  > >  16 )  &  15 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											streamAddress  =  Cmd2  &  0xFFFF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											currentFunction  =  ReadXFData ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											minCommandSize  =  streamSize  *  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											readOpcode  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  GX_LOAD_INDX_A :  //used for position matrices
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										SWLoadIndexedXF ( DataReadU32 ( ) ,  0xC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  GX_LOAD_INDX_B :  //used for normal matrices
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										SWLoadIndexedXF ( DataReadU32 ( ) ,  0xD ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  GX_LOAD_INDX_C :  //used for postmatrices
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										SWLoadIndexedXF ( DataReadU32 ( ) ,  0xE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  GX_LOAD_INDX_D :  //used for lights
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										SWLoadIndexedXF ( DataReadU32 ( ) ,  0xF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  GX_CMD_CALL_DL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											u32  dwAddr   =  DataReadU32 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											u32  dwCount  =  DataReadU32 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ExecuteDisplayList ( dwAddr ,  dwCount ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  0x44 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// zelda 4 swords calls it and checks the metrics registers after that
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-16 23:51:41 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  GX_CMD_INVL_VC : // Invalidate (vertex cache?)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										DEBUG_LOG ( VIDEO ,  " Invalidate  (vertex cache?) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  GX_LOAD_BP_REG :  //0x61
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											u32  cmd  =  DataReadU32 ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											SWLoadBPReg ( cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-10-29 01:23:17 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// draw primitives
 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-08 15:43:41 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ( Cmd  &  0xC0 )  = =  0x80 ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											u8  vatIndex  =  Cmd  &  GX_VAT_MASK ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											u8  primitiveType  =  ( Cmd  &  GX_PRIMITIVE_MASK )  > >  GX_PRIMITIVE_SHIFT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											vertexLoader . SetFormat ( vatIndex ,  primitiveType ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// switch to primitive processing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											streamSize  =  DataReadU16 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											currentFunction  =  DecodePrimitiveStream ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											minCommandSize  =  vertexLoader . GetVertexSize ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											readOpcode  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											INCSTAT ( swstats . thisFrame . numPrimatives ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											DEBUG_LOG ( VIDEO ,  " Draw begin " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											PanicAlert ( " GFX: Unknown Opcode (0x%x). \n " ,  Cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  Init ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									inObjectStream  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									lastPrimCmd  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ResetDecoding ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ResetDecoding ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									currentFunction  =  DecodeStandard ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									minCommandSize  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									readOpcode  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								bool  CommandRunnable ( u32  iBufferSize ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( iBufferSize  <  minCommandSize ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( readOpcode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										u8  Cmd  =  DataPeek8 ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										u32  minSize  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-03-11 00:30:55 +13:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										switch  ( Cmd ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  GX_LOAD_CP_REG :  //0x08
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											minSize  =  6 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  GX_LOAD_XF_REG : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											minSize  =  5 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  GX_LOAD_INDX_A :  //used for position matrices
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											minSize  =  5 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  GX_LOAD_INDX_B :  //used for normal matrices
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											minSize  =  5 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  GX_LOAD_INDX_C :  //used for postmatrices
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											minSize  =  5 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  GX_LOAD_INDX_D :  //used for lights
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											minSize  =  5 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  GX_CMD_CALL_DL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											minSize  =  9 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  GX_LOAD_BP_REG :  //0x61
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											minSize  =  5 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-10-29 01:23:17 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										// draw primitives
 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-08 15:43:41 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ( Cmd  &  0xC0 )  = =  0x80 ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												minSize  =  3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  ( iBufferSize  > =  minSize ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  Run ( u32  iBufferSize ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-13 23:54:02 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									currentFunction ( iBufferSize ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-09 01:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}