Advertisement
TerusTheBird

crappy oot actor injector

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