Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Copyright (c) 2012, Muhammad Sumyandityo Noor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
- // For reading Electronic Arts' .big files archives
- #include <stdio.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <sys/mman.h>
- #include <string.h>
- #include <stdint.h>
- // Per File Entry Headers
- struct big_entry_file_header {
- uint32_t offset; // big-endian
- uint32_t size; // big-endian
- };
- // Archive header
- struct big_header {
- char ident[4];
- uint32_t archive_size; // little-endian
- uint32_t number_of_files; // big-endian
- uint32_t first_file_offset; // big-endian
- };
- // Endian Check
- enum
- {
- O32_LITTLE_ENDIAN = 0x03020100ul,
- O32_BIG_ENDIAN = 0x00010203ul,
- O32_PDP_ENDIAN = 0x01000302ul
- };
- static const union { unsigned char bytes[4]; uint32_t value; } o32_host_order =
- { { 0, 1, 2, 3 } };
- #define O32_HOST_ORDER (o32_host_order.value)
- // byte swap 32-bit
- static unsigned int inline
- swapped( unsigned int num ) {
- return ((num>>24)&0xff) | // move byte 3 to byte 0
- ((num<<8)&0xff0000) | // move byte 1 to byte 2
- ((num>>8)&0xff00) | // move byte 2 to byte 1
- ((num<<24)&0xff000000); // byte 0 to byte 3
- }
- // convert big endian to native endian
- static unsigned int inline
- big2native( unsigned int num ) {
- if (O32_HOST_ORDER == O32_LITTLE_ENDIAN) {
- return swapped(num);
- }
- else {
- return num;
- }
- }
- // convert little endian to native endian
- static unsigned int inline
- little2native(unsigned int num) {
- if (O32_HOST_ORDER == O32_BIG_ENDIAN) {
- return swapped(num);
- }
- else {
- return num;
- }
- }
- int main( int argc, char **argv ) {
- // file stat
- struct stat sb;
- // file length
- off_t len;
- // mapped memory address
- char *p;
- // file handle
- int fd;
- // archive header address
- struct big_header *ph;
- // hard coded [sorry, just for test !^_^]
- fd = open("/Applications/Command & Conquer Generals/Generals Data"
- "/Terrain.big", O_RDONLY);
- if (fstat(fd, &sb) == -1) {
- perror("fstat");
- return 1;
- }
- if (!S_ISREG(sb.st_mode)) {
- fprintf (stderr, "%s is not a file\n", "Invalid Big File");
- return 1;
- }
- p = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
- ph = (struct big_header*) p;
- printf("Size of File : ");
- if (little2native(ph->archive_size) >= 1024*1024) {
- float s = little2native(ph->archive_size) / (1024.0f * 1024.0f);
- printf("%.2f MB", s);
- }
- else if (little2native(ph->archive_size) >= 1024) {
- float s = little2native(ph->archive_size) / 1024.0f;
- printf("%.2f KB", s);
- }
- else {
- printf("%ul bytes", little2native(ph->archive_size));
- }
- printf("\n");
- printf("Number of Files : %u\n", big2native(ph->number_of_files));
- printf("First File Offset : 0x%x\n", big2native(ph->first_file_offset));
- char *f = p + sizeof(struct big_header);
- char *d = f;
- int i;
- for (i = 0; i < big2native(ph->number_of_files); ++i) {
- struct big_entry_file_header *eh = (struct big_entry_file_header*)d;
- d += sizeof(struct big_entry_file_header);
- printf("%s - ", d);
- while (*d != '\0') {
- ++d;
- }
- ++d;
- printf("Size %u, Offset 0x%x\n", big2native(eh->size),
- big2native(eh->offset));
- }
- close(fd);
- munmap(p, sb.st_size);
- return 0;
- }
Add Comment
Please, Sign In to add comment