// pack-u8.c by Superken7 - internal beta version. // BETA VERSION. Does NOT support packing subdirectories // Based on magicus' parse-u8.c // Sorry, i was also too lazy to get all the functions needed // from seghers tools.c , so seghers tools' source code is required. #define _GNU_SOURCE #include #include #include #include #include #include #include #include "tools.h" #define round_up(x,n) (-(-(x) & -(n))) #define round64(x) round_up(x,0x40) #define round32(x) round_up(x,0x20) #define round16(x) round_up(x,0x10) #define ERROR(s) do { fprintf(stderr, s "\n"); exit(1); } while (0) static FILE *fp; static char *outdir; typedef struct { u16 type; u16 name_offset; u32 data_offset; // == absolut offset frn U.8- headerns brjan u32 size; // last included file num for directories } U8_node; typedef struct { u32 tag; // 0x55AA382D "U.8-" u32 rootnode_offset; // offset to root_node, always 0x20. u32 header_size; // size of header from root_node to end of string table. u32 data_offset; // offset to data -- this is rootnode_offset + header_size, aligned to 0x40. u8 zeroes[16]; } U8_archive_header; typedef char U8_string[256]; int write_file(char *path, FILE *fout) { u8 buffer[4096]; u32 size, tot_size; FILE *fin; fin = fopen(path, "rb"); if (fin == NULL) return 0; tot_size = 0; while(!feof(fin)) { size = fread((u8*)buffer, 1, 4096, fin); tot_size += size; fwrite((u8*)buffer, size, 1, fout); } while(tot_size - round32(tot_size) != 0) { fputc(0, fout); tot_size++; } fclose(fin); return 1; } u32 get_num_entries(DIR *d) { u32 num; struct dirent *dir; num = 0; rewinddir(d); while((dir=readdir(d)) != NULL) { // printf("#%d %s\n",num+1, dir->d_name); num++; } rewinddir(d); return num; } int build_strings(U8_string *strings, DIR *dir) { int i = 0; struct stat st; struct dirent *d; u16 name_off = 3; // 0x00 + "." + 0x00 u32 size; rewinddir(dir); while((d=readdir(dir)) != NULL) { if (!strcmp(d->d_name, ".") || (!strcmp(d->d_name, ".."))) continue; strcpy(strings[i], (char*)(d->d_name)); stat(d->d_name, &st); //printf("#%d %s\n",i+1,d->d_name); fflush(stdout); name_off += strlen(strings[i]) +1; i++; } return name_off; } int build_nodes(U8_node *nodes, U8_string *strings, DIR *dir, u32 strings_size) { int i = 0; int j; struct stat st; struct dirent *d; u16 name_off = 3; // 0x00 + "." + 0x00 u32 data_off; u32 nodes_size; u32 size; u32 filedata_off; rewinddir(dir); while((d=readdir(dir)) != NULL) { if (!strcmp(d->d_name, ".") || (!strcmp(d->d_name, ".."))) continue; stat(d->d_name, &st); if (S_ISDIR(st.st_mode)) { nodes[i].type = be16("\x01\x00"); // printf("DIR!\n"); } else { nodes[i].type = be16("\x00\x00"); // printf("FILE!\n"); } size = st.st_size; nodes[i].size = size; data_off = round32(data_off + size); nodes[i].name_offset = be16((u8*)&name_off); name_off += strlen(strings[i]) +1; i++; } filedata_off = 0; nodes_size = (i+2)*sizeof(U8_node); /* (root node + ./ node + num_files) *size(node) */ for(j=0; j