Advertisement
Guest User

n64 controller data loader idea

a guest
Jan 25th, 2020
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.52 KB | None | 0 0
  1. /* boilerplate */
  2. typedef unsigned char  u8;
  3. typedef unsigned short u16;
  4. typedef unsigned int   u32;
  5. typedef char  s8;
  6. typedef short s16;
  7. typedef int   s32;
  8.  
  9. /* loader state */
  10. static u32 l_state = 0; /* 5 bits */
  11. static u8  l_state_load = 0;
  12.  
  13. static u32 temp_data = 0;
  14. static u8  temp_data_pos = 0;
  15. static u8  temp_data_length = 0;
  16.  
  17. int temp_data_update( u8 bit, u32* var ) {
  18.     if( temp_data_length == 0 ) return 0;
  19.     temp_data = ( temp_data << 1 ) | ( bit & 1 );
  20.     ++temp_data_pos;
  21.     if( temp_data_pos >= temp_data_length ) {
  22.         if( var != NULL )
  23.             *var = temp_data;
  24.         temp_data = 0;
  25.         temp_data_pos = 0;
  26.         temp_data_length = 0;
  27.         return 2;
  28.     }
  29.     return 1;
  30. }
  31.  
  32. /* never call this with a length less than 2 */
  33. int temp_data_start( u8 bit, u32 length ) {
  34.     temp_data = temp_data_pos = temp_data_length = 0;
  35.     temp_data_update( bit, NULL );
  36. }
  37.  
  38. /* data loader state */
  39. static u8  rd_state = 0; /* 0 = length begin; 1 = length; 2 = pos begin; 3 = pos; 4 = bytes begin; 5 = bytes; */
  40.  
  41. static u32 rd_length = 0; /* 23 bits */
  42. static u8* rd_address = NULL; /* 32 bits */
  43. static u32 rd_pos = 0;
  44.  
  45.  
  46.  
  47. /* this gets called every time we poll the controllers */
  48. void load_data( void ) {
  49.     u32 pads[ 3 ];
  50.    
  51.     /* get pad state with magic */
  52.     pads[ 0 ] = get_pad_voodoo( CONTROLLER_2 );
  53.     pads[ 1 ] = get_pad_voodoo( CONTROLLER_3 );
  54.     pads[ 2 ] = get_pad_voodoo( CONTROLLER_4 );
  55.    
  56.     for( i = 0; i < 96; ++i ) {
  57.         u8 bit_number;
  58.        
  59.         /* get the current bit number */
  60.         bit_number = i & 31;
  61.        
  62.         /* skip the unused bits in the N64 pad */
  63.         if( bit_number != 8 && bit_number != 9 ) {
  64.             u8 bit;
  65.             /* get the next bit */
  66.             bit = ( pads[ i >> 5 ] >> bit_number ) & 1;
  67.            
  68.             switch( l_state & 31 ) {
  69.                 case 0: { /* load a new state */
  70.                     if( l_state_load ) {
  71.                         temp_data_start( bit, 5 );
  72.                         l_state_load = 0;
  73.                     } else {
  74.                         temp_data_update( bit, &l_state ); /* I don't know if I like this */
  75.                         l_state_load = 1;
  76.                     }
  77.                 } break; /* if we just keep loading state 0 over and over its basically a NOP */
  78.                
  79.                 case 1: { /* read raw bytes to memory */
  80.                     switch( rd_state ) {
  81.                        
  82.                         /* get the length */
  83.                         case 0: {
  84.                             rd_address = NULL;
  85.                             rd_length = 0;
  86.                             temp_data_start( bit, 23 );
  87.                             rd_state = 1;
  88.                         } break;
  89.                         case 1: {
  90.                             if( temp_data_update( bit, &rd_length ) == 2 )
  91.                                 rd_state = 2;
  92.                         } break;
  93.                        
  94.                         /* get the pointer */
  95.                         case 2: {
  96.                             temp_data_start( bit, 32 );
  97.                             rd_state = 3;
  98.                         } break;
  99.                         case 3: {
  100.                             if( temp_data_update( bit, (u32*)(&rd_address) ) == 2 )
  101.                                 rd_state = 4;
  102.                         } break;
  103.                        
  104.                         /* load data a byte at a time */
  105.                         case 4: { /* start loading a byte */
  106.                             temp_data_start( bit, 8 );
  107.                             rd_state = 5;
  108.                         } break;
  109.                         case 5: {
  110.                             u32 byte;
  111.                             if( temp_data_update( bit, &byte ) == 2 ) { /* if the byte read is actually finished */
  112.                                 if( rd_pos < rd_length ) /* prevent corruption */
  113.                                     rd_address[ rd_pos ] = byte & 255; /* actually write to the memory */
  114.                                
  115.                                 ++rd_pos;
  116.                                 if( rd_pos < rd_length ) { /* check if we're at the end of the write */
  117.                                     rd_state = 4; /* if not then read another byte */
  118.                                 } else {
  119.                                     /* end the read and get another command */
  120.                                     rd_state = 0;
  121.                                     l_state_load = 1;
  122.                                     l_state = 0;
  123.                                 }
  124.                             }
  125.                         } break;
  126.                        
  127.                         default: break;
  128.                     }
  129.                 } break;
  130.                
  131.                 default: break; /* this should never happen */
  132.             }
  133.         }
  134.     }
  135. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement