Advertisement
TerusTheBird

n64 stuff

Feb 2nd, 2020
379
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.12 KB | None | 0 0
  1. // Test actor
  2.  
  3. #define is_debug 0
  4.  
  5. #if is_debug == 1
  6. #include <z64ovl/oot/debug.h>
  7. #define free_memory 0x80600000 /* 2MB */
  8. #else
  9. #include <z64ovl/oot/u10.h>
  10. #define free_memory 0x80400000 /* 4MB */
  11. #endif
  12.  
  13. #define framebuffer_size 0x25800 /* 320x240 16bpp */
  14.  
  15. const u8 digit_gfx[ 112 ];
  16.  
  17. // entity structure
  18. typedef struct entity_t entity_t;
  19. struct entity_t {
  20.     z64_actor_t actor;
  21.     u16* framebuffer;
  22.     u32 randu_state;
  23.     u8  ll_command;
  24.     u16 command;
  25.     u8  input_bytes[11];
  26.    
  27.     u32* dma_vram_addr;
  28.     u32* dma_vrom_addr;
  29.     u32  dma_size;
  30.     u32  dma_unknown;
  31.    
  32.     u8* pointer;
  33.     void (*func_pointer)( entity_t*, z64_global_t* );
  34. };
  35.  
  36. // Actor Information
  37. #define OBJ_ID 1 // Object to use
  38.  
  39. inline u32  randu_get(    entity_t* entity );
  40. inline void print_digit(    u16* framebuffer, u8  digit,  u16 x, u16 y );
  41. void        print_number32( u16* framebuffer, u32 number, u16 x, u16 y );
  42. void        print_number16( u16* framebuffer, u16 number, u16 x, u16 y );
  43. void        print_number8(  u16* framebuffer, u8  number, u16 x, u16 y );
  44. void        print_bytes(    u16* framebuffer, u8* bytes, u32 amount, u16 x, u16 y, u16 bytes_per_line );
  45.  
  46. void get_pad_input( z64_global_t* global, u8 pad_number, u8* out_bytes ) {
  47.     union {
  48.         z64_controller_t pad;
  49.         u32 word;
  50.     } data;
  51.     pad_number &= 3;
  52.     if( global->common.input[ pad_number ].status != 0 ) {
  53.         *((u32*)out_bytes) = 0xFF3FFFFF;
  54.         return;
  55.     }
  56.     data.pad = global->common.input[ pad_number ].raw;
  57.     data.word &= 0xFF3FFFFF;
  58.     *((u32*)out_bytes) = data.word;
  59. }
  60.  
  61. void get_input( entity_t* entity, z64_global_t* global ) {
  62.     u8 ib[ 16 ], *ob;
  63.    
  64.     get_pad_input( global, 0, &ib[  0 ] );
  65.     get_pad_input( global, 1, &ib[  4 ] );
  66.     get_pad_input( global, 2, &ib[  8 ] );
  67.     get_pad_input( global, 3, &ib[ 12 ] );
  68.    
  69.     print_bytes( entity->framebuffer, ib, 16, 24, 240 - 64, 4 );
  70.    
  71.     ob = entity->input_bytes;
  72.    
  73.     // ib = bytes from controller input
  74.     // ob = extracted bytes, stored in entity
  75.     // read pad bits sequentially (bit twiddling hell)
  76.     ob[  0 ]  = ib[  4 ];
  77.     ob[  1 ]  = ib[  5 ] << 2;
  78.     ob[  1 ] |= ib[  6 ] >> 6;
  79.     ob[  2 ]  = ib[  6 ] << 2;
  80.     ob[  2 ] |= ib[  7 ] >> 6;
  81.     ob[  3 ]  = ib[  7 ] << 2;
  82.     ob[  3 ] |= ib[  8 ] >> 6;
  83.     ob[  4 ]  = ib[  8 ] << 2;
  84.     ob[  4 ] |= ib[  9 ] >> 4;
  85.     ob[  5 ]  = ib[  9 ] << 4;
  86.     ob[  5 ] |= ib[ 10 ] >> 4;
  87.     ob[  6 ]  = ib[ 10 ] << 4;
  88.     ob[  6 ] |= ib[ 11 ] >> 4;
  89.     ob[  7 ]  = ib[ 11 ] << 4;
  90.     ob[  7 ] |= ib[ 12 ] >> 4;
  91.     ob[  8 ]  = ib[ 12 ] << 4;
  92.     ob[  8 ] |= ib[ 13 ] >> 2;
  93.     ob[  9 ]  = ib[ 13 ] << 6;
  94.     ob[  9 ] |= ib[ 14 ] >> 2;
  95.     ob[ 10 ]  = ib[ 14 ] << 6;
  96.     ob[ 10 ] |= ib[ 15 ] >> 2;
  97.     entity->ll_command = ib[ 15 ] & 3;
  98. }
  99.  
  100. int run_commands( entity_t* entity, z64_global_t* global ) {
  101.     union {
  102.         u8**  in_u8p;
  103.         u32** in_u32p;
  104.         void (*in_fp)(entity_t *, z64_global_t *);
  105.        
  106.         u64* in_u64;
  107.         u32* in_u32;
  108.         u16* in_u16;
  109.         u8*  in_u8;
  110.         u32  word;
  111.     } types;
  112.     types.in_u8 = entity->input_bytes;
  113.    
  114.     switch( entity->ll_command ) {
  115.         case 0: break; // NOP
  116.         case 1: { // load new meta command
  117.             entity->command = *( types.in_u16 );
  118.         } break;
  119.         case 2: { // run meta command
  120.             // ----------------------------------
  121.             switch( entity->command ) {
  122.                
  123.                 case 0: { // set data pointer
  124.                     entity->pointer = types.in_u8p[ 0 ];
  125.                 } break;
  126.                
  127.                 case 1: { // set function pointer
  128.                     entity->func_pointer = *( types.in_fp );
  129.                 } break;
  130.                
  131.                 case 2: { // jump to function pointer
  132.                     entity->func_pointer( entity, global );
  133.                 } break;
  134.                
  135.                 case 3: { // write 11 bytes to pointer
  136.                     u8 i;
  137.                     for( i = 0; i < 11; ++i )
  138.                         *(entity->pointer++) = entity->input_bytes[ i ];
  139.                 } break;
  140.                
  141.                 case 4: { // write <= 10 bytes to pointer
  142.                     u8 count, i;
  143.                     count = entity->input_bytes[ 10 ];
  144.                     if( count > 10 ) count = 10;
  145.                     for( i = 0; i < count; ++i )
  146.                         *(entity->pointer++) = entity->input_bytes[ i ];
  147.                 } break;
  148.                
  149.                 case 5: { // Set DMA source and dest
  150.                     entity->dma_vram_addr = types.in_u32p[ 0 ];
  151.                     entity->dma_vrom_addr = types.in_u32p[ 1 ];
  152.                 } break;
  153.                
  154.                 case 6: { // Set DMA other attributes
  155.                     entity->dma_size = types.in_u32[ 0 ];
  156.                     entity->dma_unknown = types.in_u32[ 1 ];
  157.                 } break;
  158.                
  159.                 case 7: { // Execute DMA transfer using previously set attributes
  160.                     load_data_from_rom(
  161.                         entity->dma_vram_addr,
  162.                         entity->dma_vrom_addr,
  163.                         entity->dma_size,
  164.                         entity->dma_unknown
  165.                     );
  166.                 } break;
  167.                
  168.                 case 10: { // *test* play sound
  169.                     sound_play_actor( &entity->actor, types.in_u16[ 0 ] );
  170.                 } break;
  171.                
  172.                 case 11: { // *test* draw a number on-screen
  173.                     if( entity->framebuffer != NULL )
  174.                         print_number32(
  175.                             entity->framebuffer,
  176.                             types.in_u32[ 0 ],
  177.                             types.in_u16[ 2 ],
  178.                             types.in_u16[ 3 ]
  179.                         );
  180.                 } break;
  181.                
  182.                 default: break;
  183.             }
  184.             // ----------------------------------
  185.         } break;
  186.         case 3: break; // do something
  187.         default: break; // this should never happen
  188.     }
  189. }
  190.  
  191. // ----------------------------------------------------------------------------
  192.  
  193. // .text
  194. static void create( entity_t* entity, z64_global_t* global ) {
  195.     u8 i;
  196.     entity->pointer = (u8*)free_memory;
  197.     entity->randu_state = 1;
  198.     entity->framebuffer = global->common.gfx_ctxt->frame_buffer;
  199.     entity->ll_command = 0;
  200.     entity->command = 0;
  201.     for( i = 0; i < 11; ++i )
  202.         entity->input_bytes[ i ] = 0;
  203.     entity->func_pointer = NULL;
  204.    
  205.     //*((volatile u32*)0x04400000)
  206.     *((volatile u32*)0x800A2634) = 0; // enable pad 2
  207.     *((volatile u32*)0x800A2640) = 0; // enable pad 4
  208. }
  209.  
  210. static void step( entity_t* entity, z64_global_t* global ) {
  211.     entity->framebuffer = global->common.gfx_ctxt->frame_buffer;
  212.    
  213.     get_input( entity, global );
  214.    
  215.     if( entity->framebuffer != NULL ) {
  216.         print_digit(    entity->framebuffer, entity->ll_command,   24, 56 );
  217.         print_number16( entity->framebuffer, entity->command,      24, 56 + 8 );
  218.         print_number32( entity->framebuffer, (u32)entity->pointer, 24, 56 + 16 );
  219.         print_number32( entity->framebuffer, *((volatile u32*)0x800A2634), 24, 100 );
  220.         print_number32( entity->framebuffer, *((volatile u32*)0x800A2640), 24, 108 );
  221.         print_number32( entity->framebuffer, (u32)entity->func_pointer, 24, 56 + 24 );
  222.         print_bytes(    entity->framebuffer, entity->input_bytes, 11, 24, 56 + 32, 11 );
  223.     }
  224.    
  225.    
  226.    
  227.     run_commands( entity, global );
  228. }
  229.  
  230. static void draw( entity_t* entity, z64_global_t* global ) {
  231.    
  232. }
  233.  
  234. static void destroy( entity_t* entity, z64_global_t* global ) {
  235.     u32 ent_pos;
  236.     ent_pos = ((u32)(&(entity->framebuffer))) - (u32)entity;
  237.     while( ent_pos < sizeof(entity_t) ) {
  238.         ((u8*)&entity->framebuffer)[ ent_pos ] = 0;
  239.         ++ent_pos;
  240.     }
  241. }
  242.  
  243. // .data
  244. const z64_actor_init_t init_vars = {
  245.     .number = 0xDEAD, .padding = 0xBEEF, // <-- magic values, do not change
  246. //  .number = 0x82, .padding = 0, // <-- magic values, do not change
  247.     .type = 0x06, // type = stage prop
  248.     .room = 0x00,
  249.     .flags = 0x00000030,
  250.     .object = OBJ_ID,
  251.     .instance_size = sizeof(entity_t),
  252.     .init = create,
  253.     .dest = destroy,
  254.     .main = step,
  255.     .draw = draw
  256. };
  257.  
  258. // ----------------------------------------------------------------------------
  259.  
  260. const char test1[] = "TheRealWayToGetTheTriforce";
  261.  
  262. // digits
  263. const u8 digit_gfx[ 112 ] = {
  264.     0b01110,
  265.     0b10001,
  266.     0b10011,
  267.     0b10101,
  268.     0b11001,
  269.     0b11001,
  270.     0b01110,
  271.     0b00100,
  272.     0b01100,
  273.     0b10100,
  274.     0b00100,
  275.     0b00100,
  276.     0b00100,
  277.     0b11111,
  278.     0b01110,
  279.     0b10001,
  280.     0b00001,
  281.     0b00110,
  282.     0b01100,
  283.     0b10001,
  284.     0b11111,
  285.     0b01110,
  286.     0b10001,
  287.     0b00001,
  288.     0b00110,
  289.     0b00001,
  290.     0b10001,
  291.     0b01110,
  292.     0b00010,
  293.     0b00110,
  294.     0b01010,
  295.     0b10010,
  296.     0b11111,
  297.     0b00010,
  298.     0b00111,
  299.     0b11111,
  300.     0b10000,
  301.     0b10000,
  302.     0b11110,
  303.     0b00001,
  304.     0b10001,
  305.     0b01110,
  306.     0b00110,
  307.     0b01000,
  308.     0b10000,
  309.     0b11110,
  310.     0b10001,
  311.     0b10001,
  312.     0b01110,
  313.     0b11111,
  314.     0b10001,
  315.     0b00010,
  316.     0b00100,
  317.     0b01000,
  318.     0b01000,
  319.     0b01000,
  320.     0b01110,
  321.     0b10001,
  322.     0b10001,
  323.     0b01110,
  324.     0b10001,
  325.     0b10001,
  326.     0b01110,
  327.     0b01110,
  328.     0b10001,
  329.     0b10001,
  330.     0b01111,
  331.     0b00001,
  332.     0b00001,
  333.     0b01110,
  334.     0b00100,
  335.     0b01010,
  336.     0b10001,
  337.     0b10001,
  338.     0b11111,
  339.     0b10001,
  340.     0b10001,
  341.     0b11110,
  342.     0b01001,
  343.     0b01001,
  344.     0b01110,
  345.     0b01001,
  346.     0b01001,
  347.     0b11110,
  348.     0b00110,
  349.     0b01001,
  350.     0b10000,
  351.     0b10000,
  352.     0b10000,
  353.     0b01001,
  354.     0b00110,
  355.     0b11110,
  356.     0b01001,
  357.     0b01001,
  358.     0b01001,
  359.     0b01001,
  360.     0b01001,
  361.     0b11110,
  362.     0b11111,
  363.     0b01001,
  364.     0b01000,
  365.     0b01110,
  366.     0b01000,
  367.     0b01001,
  368.     0b11111,
  369.     0b11111,
  370.     0b01001,
  371.     0b01000,
  372.     0b01110,
  373.     0b01000,
  374.     0b01000,
  375.     0b11100
  376. };
  377.  
  378. u32 randu_get( entity_t* entity ) {
  379.     if( entity == NULL ) return 0;
  380.     return entity->randu_state = ( entity->randu_state * 65539U ) & 0x7FFFFFFF;
  381. }
  382.  
  383. inline void put_pixel( u16* framebuffer, u16 x, u32 y, u16 color );
  384. void put_pixel( u16* framebuffer, u16 x, u32 y, u16 color ) {
  385.     if( x < 320 && y < 240 ) {
  386.         y *= 320;
  387.         y += x;
  388.         framebuffer[ y ] = color;
  389.     }
  390. }
  391.  
  392. void print_digit( u16* framebuffer, u8 digit, u16 x, u16 y ) {
  393.     u8 i;
  394.     digit &= 15;
  395.     digit *= 7;
  396.     for( i = 0; i < 7; ++i ) {
  397.         u8 line, pixel;
  398.         line = digit_gfx[ digit + i ];
  399.         for( pixel = 0; pixel < 5; ++pixel ) {
  400.             if( line & 0b10000 ) {
  401.                 put_pixel( framebuffer, x + pixel + 1, y + i + 1, 0 );
  402.                 put_pixel( framebuffer, x + pixel,     y + i,     0xFFFF );
  403.             }
  404.             line <<= 1;
  405.         }
  406.     }
  407. }
  408.  
  409. void print_number32( u16* framebuffer, u32 number, u16 x, u16 y ) {
  410.     u8 counter;
  411.     for( counter = 0; counter < 8; ++counter ) {
  412.         print_digit( framebuffer, number >> 28, x, y );
  413.         x += 6;
  414.         number <<= 4;
  415.     }
  416. }
  417.  
  418. void print_number16( u16* framebuffer, u16 number, u16 x, u16 y ) {
  419.     u8 counter;
  420.     for( counter = 0; counter < 4; ++counter ) {
  421.         print_digit( framebuffer, number >> 12, x, y );
  422.         x += 6;
  423.         number <<= 4;
  424.     }
  425. }
  426.  
  427. void print_number8( u16* framebuffer, u8 number, u16 x, u16 y ) {
  428.     print_digit( framebuffer, number >> 4, x,     y );
  429.     print_digit( framebuffer, number & 15, x + 6, y );
  430. }
  431.  
  432. void print_bytes( u16* framebuffer, u8* bytes, u32 amount, u16 x, u16 y, u16 bytes_per_line ) {
  433.     u16 dx, dy, i;
  434.     dx = dy = 0;
  435.     for( i = 0; i < amount; ++i ) {
  436.         print_digit( framebuffer, bytes[ i ] >> 4, x + dx,     y + dy );
  437.         print_digit( framebuffer, bytes[ i ] & 15, x + dx + 6, y + dy );
  438.        
  439.         dx += 14;
  440.         if( dx >= ( bytes_per_line * 14 ) ) {
  441.             dx = 0;
  442.             dy += 8;
  443.         }
  444.     }
  445. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement