Advertisement
TerusTheBird

overlay injector

Feb 2nd, 2020
154
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.25 KB
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <inttypes.h>
  4. #include <string.h>
  5.  
  6. #define ROM_filename_in  "clean.z64"
  7. #define ROM_filename_out "actor_test.z64"
  8.  
  9. // magic numbers for 1.0
  10. #define dmadata_pos     0x7430
  11. #define actor_list_pos  0xB5E490
  12. #define object_list_pos 0xB6EF58
  13. #define scene_list_pos  0xB71440
  14.  
  15. #define vase_actor_filenumber  0x8A
  16. #define vase_object_filenumber 614
  17.  
  18. #define vase_actor_number 130
  19. #define vase_object_number 134
  20.  
  21. #define room_filenumber  1184
  22. #define scene_filenumber 1183
  23. #define scene_number 0x26
  24.  
  25. // where you want to put the actor/object in ROM
  26. #define free_memory 0x347E040
  27.  
  28.  
  29. #define vram_pos 0x80800000
  30.  
  31. #define alloc_type 0
  32.  
  33. #pragma pack(1)
  34.  
  35. typedef struct {
  36.     uint32_t vrom_start;
  37.     uint32_t vrom_end;
  38.     uint32_t rom_start;
  39.     uint32_t rom_end;
  40. } e_dmadata_t;
  41.  
  42. typedef struct {
  43.     uint32_t vrom_start;
  44.     uint32_t vrom_end;
  45.     uint32_t vram_start;
  46.     uint32_t vram_end;
  47.     uint32_t ram_pos;
  48.     uint32_t init_pos;
  49.     uint32_t filename_pos;
  50.     uint16_t allocation_type;
  51.     uint8_t  instance_count;
  52.     uint8_t  padding;
  53. } e_actor_t;
  54.  
  55. typedef struct {
  56.     uint32_t start; // VROM
  57.     uint32_t end; // VROM
  58. } e_object_t;
  59.  
  60. typedef struct {
  61.     uint32_t vrom_start;
  62.     uint32_t vrom_end;
  63.     uint32_t title_vrom_start;
  64.     uint32_t title_vrom_end;
  65.     uint8_t  unknown;
  66.     uint8_t  scene_render_init_func_id;
  67.     uint8_t  unknown2;
  68.     uint8_t  padding;
  69. } e_scene_t;
  70.  
  71. #pragma options align=reset
  72.  
  73. inline uint32_t big_endian32( uint32_t n );
  74. uint32_t big_endian32( uint32_t n ) {
  75.     return n >> 24 | n << 24 | ( n & 0xFF0000 ) >> 8 | ( n & 0xFF00 ) << 8;
  76. }
  77.  
  78. inline uint16_t big_endian16( uint16_t n );
  79. uint16_t big_endian16( uint16_t n ) {
  80.     return n >> 8 | n << 8;
  81. }
  82.  
  83. size_t fsize( FILE* fp ){
  84.     size_t prev, fs;
  85.     if( fp == NULL ) return 0;
  86.     prev = ftell( fp );
  87.     fseek( fp, 0L, SEEK_END );
  88.     fs = ftell( fp );
  89.     fseek( fp, prev, SEEK_SET );
  90.     return fs;
  91. }
  92.  
  93. // get the position of the initialization vars in the overlay
  94. uint32_t find_initvars( uint8_t* overlay, uint32_t overlay_size ) {
  95.     uint32_t start;
  96.     if( overlay == NULL ) return 0;
  97.     if( overlay_size < 12 ) return 0;
  98.     start = overlay_size - 12;
  99.     do {
  100.         if( overlay[ start      ] == 0xDE ) // try to find deadbeef in the overlay
  101.         if( overlay[ start +  1 ] == 0xAD ) // this could potentially have false positives
  102.         if( overlay[ start + 10 ] == 0xBE )
  103.         if( overlay[ start + 11 ] == 0xEF ) {
  104.             printf( "Found init vars at %8x\n", start );
  105.             overlay[ start     ] = ( vase_actor_number >>   8 );
  106.             overlay[ start + 1 ] = ( vase_actor_number &  255 );
  107.             overlay[ start + 10 ] = 0;
  108.             overlay[ start + 11 ] = 0;
  109.             return start;
  110.         }
  111.         --start;
  112.     } while( start != 0 );
  113.     return 0; // couldn't find it
  114. }
  115.  
  116. int zscene_update( uint8_t* zscene, uint32_t size, uint32_t room_pos, uint32_t room_size ) {
  117.     uint32_t i, *ptr;
  118.     if( zscene == NULL ) return 0;
  119.     for( i = 0; i < size; i += 8 ) {
  120.         if( zscene[ i ] == 4 ) {
  121.             uint16_t room_table;
  122.             room_table = zscene[ i + 6 ];
  123.             room_table <<= 8;
  124.             room_table |= zscene[ i + 7 ];
  125.             if( room_table >= size ) return 0; // room command is corrupted?
  126.             printf( "Found room table list at %4x\n", room_table );
  127.             ptr = (uint32_t*) &zscene[ room_table ];
  128.             ptr[ 0 ] = big_endian32( room_pos );
  129.             ptr[ 1 ] = big_endian32( room_pos + room_size );
  130.             printf(
  131.                 "Room pos: %8x\n"
  132.                 "Room end: %8x\n",
  133.                 room_pos,
  134.                 room_pos + room_size
  135.             );
  136.             return 1;
  137.         }
  138.     }
  139.     return 0; // couldn't find the room command
  140. }
  141.  
  142. void crc_fix( uint8_t* data ) {
  143.     uint32_t d, r, t1, t2, t3, t4, t5, t6, i;
  144.     uint32_t* crc_ptr;
  145.    
  146.     t1 = t2 = t3 = t4 = t5 = t6 = 0xDF26F436;
  147.    
  148.     for( i = 0x1000; i < 0x101000; i += 4 ) {
  149.         d = (uint32_t)((data[i] << 24) | (data[i + 1] << 16) | (data[i + 2] << 8) | data[i + 3]);
  150.         if( ( t6 + d ) < t6 ) ++t4;
  151.         t6 += d;
  152.         t3 ^= d;
  153.         r = (d << (int)(d & 0x1F)) | (d >> (32 - (int)(d & 0x1F)));
  154.         t5 += r;
  155.         t2 = ( t2 > d ) ? t2 ^ r : t2 ^ ( t6 ^ d );
  156.         t1 += (uint32_t)((data[0x750 + (i & 0xFF)] << 24) | (data[0x751 + (i & 0xFF)] << 16) | (data[0x752 + (i & 0xFF)] << 8) | data[0x753 + (i & 0xFF)]) ^ d;
  157.     }
  158.    
  159.     crc_ptr = (uint32_t*)(&data[16]);
  160.     crc_ptr[ 0 ] = big_endian32( t6 ^ t4 ^ t3 );
  161.     crc_ptr[ 1 ] = big_endian32( t5 ^ t2 ^ t1 );
  162. }
  163.  
  164. inline uint32_t round_up4( uint32_t n );
  165. uint32_t round_up4( uint32_t n ) {
  166.     uint32_t n4;
  167.     n4 = n & 3;
  168.     if( n4 == 0 ) return n;
  169.     if( n4 == 1 ) return n + 3;
  170.     if( n4 == 2 ) return n + 2;
  171.     if( n4 == 3 ) return n + 1;
  172.     return n;
  173. }
  174.  
  175. int main( void ) {
  176.     uint8_t* rom_buffer;
  177.     uint32_t rom_size;
  178.     e_dmadata_t* filesystem;
  179.     e_actor_t*   actors;
  180.     e_object_t*  objects;
  181.     e_scene_t*   scenes;
  182.    
  183.     uint8_t* new_object;
  184.     uint32_t new_object_size;
  185.     uint32_t new_object_pos;
  186.    
  187.     uint8_t* new_actor;
  188.     uint32_t new_actor_size;
  189.     uint32_t new_actor_pos;
  190.     uint32_t new_actor_initpos;
  191.    
  192.     uint8_t* new_scene;
  193.     uint32_t new_scene_size;
  194.     uint32_t new_scene_pos;
  195.    
  196.     uint8_t* new_room;
  197.     uint32_t new_room_size;
  198.     uint32_t new_room_pos;
  199.    
  200.     printf( "%zi\n", sizeof(e_actor_t) );
  201.    
  202.     rom_buffer = new_object = new_actor = new_scene = new_room = NULL;
  203.    
  204.     {
  205.     FILE* fp;
  206.     fp = fopen( ROM_filename_in, "rb" );
  207.     if( fp == NULL ) return 0;
  208.     rom_size = fsize( fp );
  209.     rom_buffer = (uint8_t*)malloc( rom_size );
  210.     if( rom_buffer == NULL ) {
  211.         fclose( fp );
  212.         goto end_prog;
  213.     }
  214.     fread( rom_buffer, 1, rom_size, fp );
  215.     fclose( fp );
  216.     }
  217.     printf( "Opened %s\n", ROM_filename_in );
  218.    
  219. /*  {
  220.     FILE* fp;
  221.     fp = fopen( "zobj.zobj", "rb" );
  222.     if( fp == NULL ) goto end_prog;
  223.     new_object_size = fsize( fp );
  224.     new_object = (uint8_t*)malloc( new_object_size );
  225.     if( new_object == NULL ) {
  226.         fclose( fp );
  227.         goto end_prog;
  228.     }
  229.     fread( new_object, 1, new_object_size, fp );
  230.     fclose( fp );
  231.     }*/
  232.    
  233.     {
  234.     FILE* fp;
  235.     fp = fopen( "actor.zovl", "rb" );
  236.     if( fp == NULL ) goto end_prog;
  237.     new_actor_size = fsize( fp );
  238.     new_actor = (uint8_t*)malloc( new_actor_size );
  239.     if( new_actor == NULL ) {
  240.         fclose( fp );
  241.         goto end_prog;
  242.     }
  243.     fread( new_actor, 1, new_actor_size, fp );
  244.     fclose( fp );
  245.     }
  246.    
  247.     {
  248.     FILE* fp;
  249.     fp = fopen( "try farts (Scene).zscene", "rb" );
  250.     if( fp == NULL ) goto end_prog;
  251.     new_scene_size = fsize( fp );
  252.     new_scene = (uint8_t*)malloc( new_scene_size );
  253.     if( new_scene == NULL ) {
  254.         fclose( fp );
  255.         goto end_prog;
  256.     }
  257.     fread( new_scene, 1, new_scene_size, fp );
  258.     fclose( fp );
  259.     }
  260.    
  261.     {
  262.     FILE* fp;
  263.     fp = fopen( "try farts (Room 0).zmap", "rb" );
  264.     if( fp == NULL ) goto end_prog;
  265.     new_room_size = fsize( fp );
  266.     new_room = (uint8_t*)malloc( new_room_size );
  267.     if( new_room == NULL ) {
  268.         fclose( fp );
  269.         goto end_prog;
  270.     }
  271.     fread( new_room, 1, new_room_size, fp );
  272.     fclose( fp );
  273.     }
  274.    
  275.     filesystem = (e_dmadata_t*)( &rom_buffer[ dmadata_pos ] );
  276.     actors     = (e_actor_t*)(   &rom_buffer[ actor_list_pos ] );
  277. //  objects    = (e_object_t*)(  &rom_buffer[ object_list_pos ] );
  278.     scenes     = (e_scene_t*)(   &rom_buffer[ scene_list_pos ] );
  279.    
  280.     // get position of init vars in actor
  281.     new_actor_initpos = find_initvars( new_actor, new_actor_size );
  282.     new_actor_pos  = free_memory;
  283.     new_scene_pos  = new_actor_pos + new_actor_size;
  284.     new_room_pos   = new_scene_pos + new_scene_size;
  285. //  new_object_pos = new_room_pos + new_room_size;
  286.    
  287.     zscene_update( new_scene, new_scene_size, new_room_pos, new_room_size );
  288.    
  289.     printf(
  290.         "Actor ROM:      %8x\n"
  291.         "Actor RAM:      %8x\n"
  292.         "Actor Init RAM: %8x\n"
  293.         "Actor size:     %8x\n",
  294.         new_actor_pos,
  295.         0x80800000,
  296.         0x80800000 + new_actor_initpos,
  297.         new_actor_size
  298.     );
  299.    
  300. /*  printf(
  301.         "Object ROM:     %8x\n"
  302.         "Object size:    %8x\n",
  303.         new_object_pos,
  304.         new_object_size
  305.     );*/
  306.    
  307.     printf( "Scene ROM: %8x\n", new_scene_pos );
  308.     printf( "Room ROM:  %8x\n", new_room_pos );
  309.    
  310.     // inject actor and object
  311.     memcpy( &rom_buffer[ new_actor_pos  ], new_actor,  new_actor_size  );
  312.     memcpy( &rom_buffer[ new_scene_pos  ], new_scene,  new_scene_size  );
  313.     memcpy( &rom_buffer[ new_room_pos   ], new_room,   new_room_size   );
  314. //  memcpy( &rom_buffer[ new_object_pos ], new_object, new_object_size );
  315.    
  316.    
  317.     // inject scene into filesystem
  318.     filesystem[ scene_filenumber ].vrom_start = big_endian32( new_scene_pos );
  319.     filesystem[ scene_filenumber ].vrom_end   = big_endian32( new_scene_pos + new_scene_size );
  320.     filesystem[ scene_filenumber ].rom_start  = big_endian32( new_scene_pos );
  321.     filesystem[ scene_filenumber ].rom_end    = 0U;
  322.     printf( "Scene DMA pos: %8zx\n", dmadata_pos + ( sizeof(e_dmadata_t) * scene_filenumber ) );
  323.    
  324.     // inject room into filesystem
  325.     filesystem[ room_filenumber ].vrom_start = big_endian32( new_room_pos );
  326.     filesystem[ room_filenumber ].vrom_end   = big_endian32( new_room_pos + new_room_size );
  327.     filesystem[ room_filenumber ].rom_start  = big_endian32( new_room_pos );
  328.     filesystem[ room_filenumber ].rom_end    = 0U;
  329.     printf( "Room DMA pos: %8zx\n", dmadata_pos + ( sizeof(e_dmadata_t) * room_filenumber ) );
  330.    
  331.     // inject scene into scene list
  332.     scenes[ scene_number ].vrom_start = big_endian32( new_scene_pos );
  333.     scenes[ scene_number ].vrom_end   = big_endian32( new_scene_pos + new_scene_size );
  334.     // everything else should be already correct here
  335.    
  336.     /*// insert object into filesystem
  337.     filesystem[ vase_object_filenumber ].vrom_start = big_endian32( new_object_pos );
  338.     filesystem[ vase_object_filenumber ].vrom_end   = big_endian32( new_object_pos + new_object_size );
  339.     filesystem[ vase_object_filenumber ].rom_start  = big_endian32( new_object_pos );
  340.     filesystem[ vase_object_filenumber ].rom_end    = 0U;
  341.    
  342.     // insert object into object table
  343.     objects[ vase_object_number ].start = big_endian32( new_object_pos );
  344.     objects[ vase_object_number ].end   = big_endian32( new_object_pos + new_object_size );
  345.     */
  346.    
  347.     // insert actor into filesystem
  348.     filesystem[ vase_actor_filenumber ].vrom_start = big_endian32( new_actor_pos );
  349.     filesystem[ vase_actor_filenumber ].vrom_end   = big_endian32( new_actor_pos + new_actor_size );
  350.     filesystem[ vase_actor_filenumber ].rom_start  = big_endian32( new_actor_pos );
  351.     filesystem[ vase_actor_filenumber ].rom_end    = 0U;
  352.     printf( "Actor DMA pos: %8zx\n", dmadata_pos + ( sizeof(e_dmadata_t) * vase_actor_filenumber ) );
  353.    
  354.    
  355.     // insert actor into actor table
  356.     actors[ vase_actor_number ].vrom_start = big_endian32( new_actor_pos );
  357.     actors[ vase_actor_number ].vrom_end   = big_endian32( new_actor_pos + new_actor_size );
  358.     actors[ vase_actor_number ].vram_start = big_endian32( vram_pos );
  359.     actors[ vase_actor_number ].vram_end   = big_endian32( vram_pos + new_actor_size );
  360.     actors[ vase_actor_number ].ram_pos    = 0;
  361.     actors[ vase_actor_number ].init_pos   = big_endian32( vram_pos + new_actor_initpos );
  362.     actors[ vase_actor_number ].filename_pos = 0U;
  363.     actors[ vase_actor_number ].allocation_type = big_endian16( alloc_type );
  364.     actors[ vase_actor_number ].instance_count = 0; // ???
  365.     actors[ vase_actor_number ].padding = 0;
  366.     printf( "Actor list pos: %8zx\n", actor_list_pos + ( sizeof(e_actor_t) * vase_actor_number ) );
  367.    
  368.     crc_fix( rom_buffer );
  369.    
  370.     {
  371.     FILE* fp;
  372.     fp = fopen( ROM_filename_out, "wb" );
  373.     if( fp != NULL ) {
  374.         fwrite( rom_buffer, 1, rom_size, fp );
  375.         fclose( fp );
  376.     }
  377.     }
  378.     printf( "Wrote out %s\n", ROM_filename_out );
  379.    
  380. end_prog:
  381.     if( rom_buffer != NULL ) free( rom_buffer );
  382.     if( new_object != NULL ) free( new_object );
  383.     if( new_actor  != NULL ) free( new_actor );
  384.     if( new_scene  != NULL ) free( new_scene );
  385.     if( new_room   != NULL ) free( new_room );
  386.    
  387.     return 0;
  388. }
Advertisement
RAW Paste Data Copied
Advertisement