Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <inttypes.h>
- #include <string.h>
- // magic numbers for 1.0
- #define dmadata_pos 0x7430U
- #define actor_list_pos 0xB5E490U
- #define object_list_pos 0xB6EF58U
- #define scene_list_pos 0xB71440U
- #define vase_actor_filenumber 138U
- #define vase_object_filenumber 614U
- #define vase_actor_number 130U
- #define vase_object_number 134U
- #define room_filenumber 1184U
- #define scene_filenumber 1183U
- #define scene_number 0x26U
- // where you want to put the actor/object in ROM
- #define free_memory 0x347E040U
- #define vram_pos 0x80800000U
- #define alloc_type 0
- #pragma pack(1)
- typedef struct {
- uint32_t vrom_start;
- uint32_t vrom_end;
- uint32_t rom_start;
- uint32_t rom_end;
- } e_dmadata_t;
- typedef struct {
- uint32_t vrom_start;
- uint32_t vrom_end;
- uint32_t vram_start;
- uint32_t vram_end;
- uint32_t ram_pos;
- uint32_t init_pos;
- uint32_t filename_pos;
- uint16_t allocation_type;
- uint8_t instance_count;
- uint8_t padding;
- } e_actor_t;
- typedef struct {
- uint32_t start; // VROM
- uint32_t end; // VROM
- } e_object_t;
- typedef struct {
- uint32_t vrom_start;
- uint32_t vrom_end;
- uint32_t title_vrom_start;
- uint32_t title_vrom_end;
- uint8_t unknown;
- uint8_t scene_render_init_func_id;
- uint8_t unknown2;
- uint8_t padding;
- } e_scene_t;
- #pragma options align=reset
- inline uint32_t big_endian32( uint32_t n );
- uint32_t big_endian32( uint32_t n ) {
- return n >> 24 | n << 24 | ( n & 0xFF0000 ) >> 8 | ( n & 0xFF00 ) << 8;
- }
- inline uint16_t big_endian16( uint16_t n );
- uint16_t big_endian16( uint16_t n ) {
- return n >> 8 | n << 8;
- }
- size_t fsize( FILE* fp ){
- size_t prev, fs;
- if( fp == NULL ) return 0;
- prev = ftell( fp );
- fseek( fp, 0L, SEEK_END );
- fs = ftell( fp );
- fseek( fp, prev, SEEK_SET );
- return fs;
- }
- // get the position of the initialization vars in the overlay
- uint32_t find_initvars( uint8_t* overlay, uint32_t overlay_size ) {
- uint32_t start;
- if( overlay == NULL ) return 0;
- if( overlay_size < 12 ) return 0;
- start = overlay_size - 12;
- do {
- if( overlay[ start ] == 0xDE ) // try to find deadbeef in the overlay
- if( overlay[ start + 1 ] == 0xAD ) // this could potentially have false positives
- if( overlay[ start + 10 ] == 0xBE )
- if( overlay[ start + 11 ] == 0xEF ) {
- printf( "Found init vars at %8x\n", start );
- overlay[ start ] = ( vase_actor_number >> 8 );
- overlay[ start + 1 ] = ( vase_actor_number & 255 );
- overlay[ start + 10 ] = 0;
- overlay[ start + 11 ] = 0;
- return start;
- }
- --start;
- } while( start != 0 );
- return 0; // couldn't find it
- }
- int zscene_update( uint8_t* zscene, uint32_t size, uint32_t room_pos, uint32_t room_size ) {
- uint32_t i, *ptr;
- if( zscene == NULL ) return 0;
- for( i = 0; i < size; i += 8 ) {
- if( zscene[ i ] == 4 ) {
- uint16_t room_table;
- room_table = zscene[ i + 6 ];
- room_table <<= 8;
- room_table |= zscene[ i + 7 ];
- if( room_table >= size ) return 0; // room command is corrupted?
- printf( "Found room table list at %4x\n", room_table );
- ptr = (uint32_t*) &zscene[ room_table ];
- ptr[ 0 ] = big_endian32( room_pos );
- ptr[ 1 ] = big_endian32( room_pos + room_size );
- printf(
- "Room pos: %8x\n"
- "Room end: %8x\n",
- room_pos,
- room_pos + room_size
- );
- return 1;
- }
- }
- return 0; // couldn't find the room command
- }
- void crc_fix( uint8_t* data ) {
- uint32_t d, r, t1, t2, t3, t4, t5, t6, i;
- uint32_t* crc_ptr;
- t1 = t2 = t3 = t4 = t5 = t6 = 0xDF26F436;
- for( i = 0x1000; i < 0x101000; i += 4 ) {
- d = (uint32_t)((data[i] << 24) | (data[i + 1] << 16) | (data[i + 2] << 8) | data[i + 3]);
- if( ( t6 + d ) < t6 ) ++t4;
- t6 += d;
- t3 ^= d;
- r = (d << (int)(d & 0x1F)) | (d >> (32 - (int)(d & 0x1F)));
- t5 += r;
- t2 = ( t2 > d ) ? t2 ^ r : t2 ^ ( t6 ^ d );
- t1 += (uint32_t)((data[0x750 + (i & 0xFF)] << 24) | (data[0x751 + (i & 0xFF)] << 16) | (data[0x752 + (i & 0xFF)] << 8) | data[0x753 + (i & 0xFF)]) ^ d;
- }
- crc_ptr = (uint32_t*)(&data[16]);
- crc_ptr[ 0 ] = big_endian32( t6 ^ t4 ^ t3 );
- crc_ptr[ 1 ] = big_endian32( t5 ^ t2 ^ t1 );
- }
- int main( void ) {
- uint8_t* rom_buffer;
- uint32_t rom_size;
- e_dmadata_t* filesystem;
- e_actor_t* actors;
- e_object_t* objects;
- e_scene_t* scenes;
- uint8_t* new_object;
- uint32_t new_object_size;
- uint32_t new_object_pos;
- uint8_t* new_actor;
- uint32_t new_actor_size;
- uint32_t new_actor_pos;
- uint32_t new_actor_initpos;
- uint8_t* new_scene;
- uint32_t new_scene_size;
- uint32_t new_scene_pos;
- uint8_t* new_room;
- uint32_t new_room_size;
- uint32_t new_room_pos;
- rom_buffer = new_object = new_actor = new_scene = new_room = NULL;
- {
- FILE* fp;
- fp = fopen( "oot_1u_unmodified.z64", "rb" ); // uncompressed 1.0 rom
- if( fp == NULL ) return 0;
- rom_size = fsize( fp );
- rom_buffer = (uint8_t*)malloc( rom_size );
- if( rom_buffer == NULL ) {
- fclose( fp );
- goto end_prog;
- }
- fread( rom_buffer, 1, rom_size, fp );
- fclose( fp );
- }
- {
- FILE* fp;
- fp = fopen( "zobj.zobj", "rb" ); // seagull object
- if( fp == NULL ) goto end_prog;
- new_object_size = fsize( fp );
- new_object = (uint8_t*)malloc( new_object_size );
- if( new_object == NULL ) {
- fclose( fp );
- goto end_prog;
- }
- fread( new_object, 1, new_object_size, fp );
- fclose( fp );
- }
- {
- FILE* fp;
- fp = fopen( "actor.zovl", "rb" ); // custom actor overlay
- if( fp == NULL ) goto end_prog;
- new_actor_size = fsize( fp );
- new_actor = (uint8_t*)malloc( new_actor_size );
- if( new_actor == NULL ) {
- fclose( fp );
- goto end_prog;
- }
- fread( new_actor, 1, new_actor_size, fp );
- fclose( fp );
- }
- {
- FILE* fp;
- fp = fopen( "try_farts_scene.zscene", "rb" ); // actor test map scene (2011 triforce room)
- if( fp == NULL ) goto end_prog;
- new_scene_size = fsize( fp );
- new_scene = (uint8_t*)malloc( new_scene_size );
- if( new_scene == NULL ) {
- fclose( fp );
- goto end_prog;
- }
- fread( new_scene, 1, new_scene_size, fp );
- fclose( fp );
- }
- {
- FILE* fp;
- fp = fopen( "try_farts_room_0.zmap", "rb" ); // actor test map room
- if( fp == NULL ) goto end_prog;
- new_room_size = fsize( fp );
- new_room = (uint8_t*)malloc( new_room_size );
- if( new_room == NULL ) {
- fclose( fp );
- goto end_prog;
- }
- fread( new_room, 1, new_room_size, fp );
- fclose( fp );
- }
- filesystem = (e_dmadata_t*)( &rom_buffer[ dmadata_pos ] );
- actors = (e_actor_t*)( &rom_buffer[ actor_list_pos ] );
- objects = (e_object_t*)( &rom_buffer[ object_list_pos ] );
- scenes = (e_scene_t*)( &rom_buffer[ scene_list_pos ] );
- // get position of init vars in actor
- new_actor_initpos = find_initvars( new_actor, new_actor_size );
- new_actor_pos = free_memory;
- new_object_pos = new_actor_pos + new_actor_size;
- new_scene_pos = new_object_pos + new_object_size;
- new_room_pos = new_scene_pos + new_scene_size;
- zscene_update( new_scene, new_scene_size, new_room_pos, new_room_size ); // repoint the room ptrs
- printf(
- "Actor ROM: %8x\n"
- "Actor RAM: %8x\n"
- "Actor Init RAM: %8x\n"
- "Actor size: %8x\n",
- new_actor_pos,
- 0x80800000,
- 0x80800000 + new_actor_initpos,
- new_actor_size
- );
- printf(
- "Object ROM: %8x\n"
- "Object size: %8x\n",
- new_object_pos,
- new_object_size
- );
- printf( "Scene ROM: %8x\n", new_scene_pos );
- printf( "Room ROM: %8x\n", new_room_pos );
- // inject actor and object
- memcpy( &rom_buffer[ new_actor_pos ], new_actor, new_actor_size );
- memcpy( &rom_buffer[ new_object_pos ], new_object, new_object_size );
- memcpy( &rom_buffer[ new_scene_pos ], new_scene, new_scene_size );
- memcpy( &rom_buffer[ new_room_pos ], new_room, new_room_size );
- // inject scene into filesystem
- filesystem[ scene_filenumber ].vrom_start = big_endian32( new_scene_pos );
- filesystem[ scene_filenumber ].vrom_end = big_endian32( new_scene_pos + new_scene_size );
- filesystem[ scene_filenumber ].rom_start = big_endian32( new_scene_pos );
- filesystem[ scene_filenumber ].rom_end = 0U;
- // inject room into filesystem
- filesystem[ room_filenumber ].vrom_start = big_endian32( new_room_pos );
- filesystem[ room_filenumber ].vrom_end = big_endian32( new_room_pos + new_room_size );
- filesystem[ room_filenumber ].rom_start = big_endian32( new_room_pos );
- filesystem[ room_filenumber ].rom_end = 0U;
- // inject scene into scene list
- scenes[ scene_number ].vrom_start = big_endian32( new_scene_pos );
- scenes[ scene_number ].vrom_end = big_endian32( new_scene_pos + new_scene_size );
- // everything else should be already correct here
- // insert object into filesystem
- filesystem[ vase_object_filenumber ].vrom_start = big_endian32( new_object_pos );
- filesystem[ vase_object_filenumber ].vrom_end = big_endian32( new_object_pos + new_object_size );
- filesystem[ vase_object_filenumber ].rom_start = big_endian32( new_object_pos );
- filesystem[ vase_object_filenumber ].rom_end = 0U;
- // insert object into object table
- objects[ vase_object_number ].start = big_endian32( new_object_pos );
- objects[ vase_object_number ].end = big_endian32( new_object_pos + new_object_size );
- // insert actor into filesystem
- filesystem[ vase_actor_filenumber ].vrom_start = big_endian32( new_actor_pos );
- filesystem[ vase_actor_filenumber ].vrom_end = big_endian32( new_actor_pos + new_actor_size );
- filesystem[ vase_actor_filenumber ].rom_start = big_endian32( new_actor_pos );
- filesystem[ vase_actor_filenumber ].rom_start = 0U;
- // uint32_t vrom_start;
- // uint32_t vrom_end;
- // uint32_t vram_start;
- // uint32_t vram_end;
- // uint32_t ram_pos;
- // uint32_t init_pos;
- // uint32_t filename_pos;
- // uint16_t allocation_type;
- // uint8_t instance_count;
- // uint8_t padding;
- // insert actor into actor table (I don't really know what I'm doing here)
- actors[ vase_actor_number ].vrom_start = big_endian32( new_actor_pos );
- actors[ vase_actor_number ].vrom_end = big_endian32( new_actor_pos + new_actor_size );
- actors[ vase_actor_number ].vram_start = big_endian32( vram_pos );
- actors[ vase_actor_number ].vram_end = big_endian32( vram_pos + new_actor_size );
- actors[ vase_actor_number ].ram_pos = 0;
- actors[ vase_actor_number ].init_pos = big_endian32( vram_pos + new_actor_initpos );
- actors[ vase_actor_number ].filename_pos = 0U;
- actors[ vase_actor_number ].allocation_type = big_endian16( alloc_type );
- actors[ vase_actor_number ].instance_count = 0; // ???
- actors[ vase_actor_number ].padding = 0;
- crc_fix( rom_buffer );
- {
- FILE* fp;
- fp = fopen( "oot_1u_maptest.z64", "wb" );
- if( fp != NULL ) {
- fwrite( rom_buffer, 1, rom_size, fp );
- fclose( fp );
- }
- }
- end_prog:
- if( rom_buffer != NULL ) free( rom_buffer );
- if( new_object != NULL ) free( new_object );
- if( new_actor != NULL ) free( new_actor );
- if( new_scene != NULL ) free( new_scene );
- if( new_room != NULL ) free( new_room );
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement