Exemple #1
0
// finds the Tyrian data directory
const char *data_dir( void )
{
	const char *dirs[] =
	{
		custom_data_dir,
		TYRIAN_DIR,
		"data",
		".",
	};
	
	static const char *dir = NULL;
	
	if (dir != NULL)
		return dir;
	
	for (uint i = 0; i < COUNTOF(dirs); ++i)
	{
		if (dirs[i] == NULL)
			continue;
		
		FILE *f = dir_fopen(dirs[i], "tyrian1.lvl", "rb");
		if (f)
		{
			fclose(f);
			
			dir = dirs[i];
			break;
		}
	}
	
	if (dir == NULL) // data not found
		dir = "";
	
	return dir;
}
Exemple #2
0
// check if file can be opened for reading
bool dir_file_exists( const char *dir, const char *file )
{
	FILE *f = dir_fopen(dir, file, "rb");
	if (f != NULL)
		fclose(f);
	return (f != NULL);
}
Exemple #3
0
// warn when dir_fopen fails
FILE *dir_fopen_warn(  const char *dir, const char *file, const char *mode )
{
	FILE *f = dir_fopen(dir, file, mode);
	
	if (f == NULL)
		fprintf(stderr, "warning: failed to open '%s': %s\n", file, strerror(errno));
	
	return f;
}
Exemple #4
0
// die when dir_fopen fails
FILE *dir_fopen_die( const char *dir, const char *file, const char *mode )
{
	FILE *f = dir_fopen(dir, file, mode);
	
	if (f == NULL)
	{
		fprintf(stderr, "error: failed to open '%s': %s\n", file, strerror(errno));
		fprintf(stderr, "error: One or more of the required Tyrian " TYRIAN_VERSION " data files could not be found.\n"
		                "       Please read the README file.\n");
		JE_tyrianHalt(1);
	}
	
	return f;
}
Exemple #5
0
// finds the Tyrian data directory
const char *data_dir( void )
{
	const char *dirs[] =
	{
		//custom_data_dir,
		"./data",
		"./Assets/data",
		"/data",
		"/Assets/data",
		"data",
		"Assets/data"
	};
	
	static const char *dir = NULL;
	
	if (dir != NULL && (dir[0] != '\0'))
		return dir;
	
	for (uint i = 0; i < COUNTOF(dirs); ++i)
	{
		
		FILE *f = dir_fopen(dirs[i], "tyrian1.lvl", "rb");
		if (f)
		{
			fclose(f);
			
			dir = dirs[i];
			break;
		}
	}
	
	if (dir == NULL) // data not found
		dir = "";
	
	return dir;
}
Exemple #6
0
static int
unpack_image(const char *infn, const char *outdn)
{
    struct imagewty_header *header;
    FILE *ifp, *lfp, *ofp;
    void *image, *curr;
    long imagesize;
    int i;

    ifp = fopen(infn, "rb");
    if (ifp == NULL) {
        fprintf(stderr, "Error: unable to open %s!\n", infn);
        return 2;
    }

    fseek(ifp, 0, SEEK_END);
    imagesize = ftell(ifp);
    fseek(ifp, 0, SEEK_SET);

    if (imagesize <= 0) {
        fprintf(stderr, "Error: Invalid file size %ld (%s)\n",
            imagesize, strerror(errno));
        return 3;
    }

    image = malloc(imagesize);
    if (!image) {
        fprintf(stderr, "Error: Unable to allocate memory for image: %ld\n", imagesize);
        return 4;
    }

    fread(image, imagesize, 1, ifp);
    fclose(ifp);

    /* Decrypt header (padded to 1024 bytes) */
    curr = rc6_decrypt_inplace(image, 1024, &header_ctx);

    /* Decrypt file headers */
    header = (struct imagewty_header*)image;
    curr = rc6_decrypt_inplace(curr, header->num_files * 1024, &fileheaders_ctx);

    /* Decrypt file contents */
    for (i=0; i < header->num_files; i++) {
        struct imagewty_file_header *filehdr;
        void *next;

        filehdr = (struct imagewty_file_header*)(image + 1024 + (i * 1024));
        next = rc6_decrypt_inplace(curr, filehdr->stored_length, &filecontent_ctx);
#if TF_DECRYPT_WORKING
        if (!(strlen(filehdr->filename) >= 4 &&
            strncmp(filehdr->filename + strlen(filehdr->filename) -4, ".fex", 4) == 0)) {
            /* Not a 'FEX' file, so we need to decrypt it even more! */
            tf_decrypt_inplace(curr, filehdr->stored_length);
        }
#endif
        curr = next;
    }

    if (flag_compat_output == OUTPUT_UNIMG) {
        lfp = dir_fopen(outdn, "base.hdr", "wb");
        if (lfp) {
            uint32_t *hdr = image + IMAGEWTY_MAGIC_LEN;
            fprintf(lfp, "%.8s\r\n", header->magic);
            for (i = 0; i < (sizeof(*header) - IMAGEWTY_MAGIC_LEN) / sizeof(uint32_t); i++)
                fprintf(lfp, "%08X\r\n", hdr[i]);
            fclose(lfp);
        }

        lfp = dir_fopen(outdn, "Filelist.txt", "wb");
    } else if (flag_compat_output == OUTPUT_IMGREPACKER) {
        lfp = dir_fopen(outdn, "image.cfg", "wb");
        if (lfp != NULL) {
            char timestr[256];
            struct tm *tm;
            time_t t;
            time(&t);
            tm = localtime(&t);
            strcpy(timestr, asctime(tm));
            /* strip newline */
            timestr[strlen(timestr) -1] = '\0';

            fputs(";/**************************************************************************/\r\n", lfp);
            fprintf(lfp, "; %s\r\n", timestr);
            fprintf(lfp, "; generated by %s\r\n", progname);
            fprintf(lfp, "; %s\r\n", infn);
            fputs(";/**************************************************************************/\r\n", lfp);
            fputs("[FILELIST]\r\n", lfp);
        }
    }

    for (i=0; i < header->num_files; i++) {
        struct imagewty_file_header *filehdr;
        char hdrfname[32], contfname[32];

        filehdr = (struct imagewty_file_header*)(image + 1024 + (i * 1024));
        if (flag_compat_output == OUTPUT_UNIMG) {
            printf("Extracting: %.8s %.16s (%u, %u)\n", 
                filehdr->maintype, filehdr->subtype,
                filehdr->original_length, filehdr->stored_length);

            sprintf(hdrfname, "%.8s_%.16s.hdr", filehdr->maintype, filehdr->subtype);
            ofp = dir_fopen(outdn, hdrfname, "wb");
            if (ofp) {
                fwrite(filehdr, filehdr->total_header_size, 1, ofp);
                fclose(ofp);
            }

            sprintf(contfname, "%.8s_%.16s", filehdr->maintype, filehdr->subtype);
            ofp = dir_fopen(outdn, contfname, "wb");
            if (ofp) {
                fwrite(image + filehdr->offset, filehdr->original_length, 1, ofp);
                fclose(ofp);
            }

            fprintf(lfp, "%s\t%s\r\n", hdrfname, contfname);
        } else if (flag_compat_output == OUTPUT_IMGREPACKER) {
	    printf("Extracting %s\n", filehdr->filename);

            ofp = dir_fopen(outdn, filehdr->filename, "wb");
            if (ofp) {
                fwrite(image + filehdr->offset, filehdr->original_length, 1, ofp);
                fclose(ofp);
            }

            fprintf(lfp, "\t{filename = INPUT_DIR .. \"%s\", maintype = \"%.8s\", subtype = \"%.16s\",},\r\n",
                filehdr->filename[0] == '/' ? filehdr->filename+1 : filehdr->filename,
                filehdr->maintype, filehdr->subtype);
        }
    }

    if (lfp && flag_compat_output == OUTPUT_IMGREPACKER) {
        /* Now print the relevant stuff for the image.cfg */
        fputs("\r\n[IMAGE_CFG]\r\n", lfp);
        fprintf(lfp, "version = 0x%06x\r\n", header->version);
        fprintf(lfp, "pid = 0x%08x\r\n", header->pid);
        fprintf(lfp, "vid = 0x%08x\r\n", header->vid);
        fprintf(lfp, "hardwareid = 0x%03x\r\n", header->hardware_id);
        fprintf(lfp, "firmwareid = 0x%03x\r\n", header->firmware_id);
        fprintf(lfp, "imagename = %s\r\n", infn);
        fputs("filelist = FILELIST\r\n", lfp);
    }

    if (lfp)
        fclose(lfp);

    return 0;
}
Exemple #7
0
/* loadAnim opens the file and loads data from it into the header structs.
 * It should take care to clean up after itself should an error occur.
 */
int JE_loadAnim( const char *filename )
{
	uint32_t i, fileSize;
	char temp[4];


	Curlpnum = -1;
	InFile = dir_fopen(data_dir(), filename, "rb");
	if(InFile == NULL)
	{
		return(-1);
	}

	fileSize = ftell_eof(InFile);
	if(fileSize < ANIM_OFFSET)
	{
		/* We don't know the exact size our file should be yet,
		 * but we do know it should be way more than this */
		fclose(InFile);
		return(-1);
	}

	/* Read in the header.  The header is 256 bytes long or so,
	 * but that includes a lot of padding as well as several
	 * vars we really don't care about.  We shall check the ID and extract
	 * the handful of vars we care about.  Every value in the header that
	 * is constant will be ignored.
	 */

	efread(&temp, 1, 4, InFile); /* The ID, should equal "LPF " */
	fseek(InFile, 2, SEEK_CUR); /* skip over this word */
	efread(&FileHeader.nlps, 2, 1, InFile); /* Number of pages */
	efread(&FileHeader.nRecords, 4, 1, InFile); /* Number of records */

	if (memcmp(temp, "LPF ", 4) != 0
	 || FileHeader.nlps == 0  || FileHeader.nRecords == 0
	 || FileHeader.nlps > 256 || FileHeader.nRecords > 65535)
	{
		fclose(InFile);
		return(-1);
	}

	/* Read in headers */
	fseek(InFile, PAGEHEADER_OFFSET, SEEK_SET);
	for (i = 0; i < FileHeader.nlps; i++)
	{
		efread(&PageHeader[i].baseRecord, 2, 1, InFile);
		efread(&PageHeader[i].nRecords,   2, 1, InFile);
		efread(&PageHeader[i].nBytes,     2, 1, InFile);
	}


	/* Now we have enough information to calculate the 'expected' file size.
	 * Our calculation SHOULD be equal to fileSize, but we won't begrudge
	 * padding */
	if (fileSize < (FileHeader.nlps-1) * ANI_PAGE_SIZE + ANIM_OFFSET
	  + PageHeader[FileHeader.nlps-1].nBytes
	  + PageHeader[FileHeader.nlps-1].nRecords * 2 + 8)
	{
		fclose(InFile);
		return(-1);
	}


	/* Now read in the palette. */
	fseek(InFile, PALETTE_OFFSET, SEEK_SET);
	for (i = 0; i < 256; i++)
	{
		efread(&colors[i].b,      1, 1, InFile);
		efread(&colors[i].g,      1, 1, InFile);
		efread(&colors[i].r,      1, 1, InFile);
		efread(&colors[i].unused, 1, 1, InFile);
	}
	set_palette(colors, 0, 255);

	/* Whew!  That was hard.  Let's go grab some beers! */
	return(0);
}
U16 MemoryAlloc(U16 size, long count, int stored_at)
{
    // Returns handle number if successful, 0 or nullptr if failure
    U16 handle = 0;
    int use_this_type;
    long toallocate;

    toallocate = count * size;
    if (toallocate <= 0)    // we failed, can't allocate > 2,147,483,647
        return 0U;          // or it wraps around to negative

    /* check structure for requested memory type (add em up) to see if
       sufficient amount is available to grant request */

    use_this_type = check_for_mem(stored_at, toallocate);
    if (use_this_type == NOWHERE)
    {
        DisplayError(stored_at, toallocate);
        goodbye();
    }

    // get next available handle

    handle = next_handle();

    if (handle >= MAXHANDLES || handle == 0)
    {
        DisplayHandle(handle);
        return 0U;
        // Oops, do something about this! ?????
    }

    // attempt to allocate requested memory type
    bool success = false;
    switch (use_this_type)
    {
    default:
    case NOWHERE: // MemoryAlloc
        use_this_type = NOWHERE; // in case nonsense value is passed
        break;

    case MEMORY: // MemoryAlloc
        // Availability of memory checked in check_for_mem()
        handletable[handle].Linearmem.memory = (BYTE *)malloc(toallocate);
        handletable[handle].Linearmem.size = toallocate;
        handletable[handle].Linearmem.stored_at = MEMORY;
        numTOTALhandles++;
        success = true;
        break;

    case DISK: // MemoryAlloc
        memfile[9] = (char)(handle % 10 + (int)'0');
        memfile[8] = (char)((handle % 100) / 10 + (int)'0');
        memfile[7] = (char)((handle % 1000) / 100 + (int)'0');
        if (disktarga)
            handletable[handle].Disk.file = dir_fopen(workdir, light_name, "a+b");
        else
            handletable[handle].Disk.file = dir_fopen(tempdir, memfile, "w+b");
        rewind(handletable[handle].Disk.file);
        if (fseek(handletable[handle].Disk.file, toallocate, SEEK_SET) != 0)
            handletable[handle].Disk.file = nullptr;
        if (handletable[handle].Disk.file == nullptr)
        {
            handletable[handle].Disk.stored_at = NOWHERE;
            use_this_type = NOWHERE;
            WhichDiskError(1);
            DisplayMemory();
            driver_buzzer(buzzer_codes::PROBLEM);
            break;
        }
        numTOTALhandles++;
        success = true;
        fclose(handletable[handle].Disk.file); // so clusters aren't lost if we crash while running
        if (disktarga)
            handletable[handle].Disk.file = dir_fopen(workdir, light_name, "r+b");
        else
            handletable[handle].Disk.file = dir_fopen(tempdir, memfile, "r+b"); // reopen
        rewind(handletable[handle].Disk.file);
        handletable[handle].Disk.size = toallocate;
        handletable[handle].Disk.stored_at = DISK;
        use_this_type = DISK;
        break;
    } // end of switch

    if (stored_at != use_this_type && debugflag == debug_flags::display_memory_statistics)
    {
        char buf[MSGLEN];
        sprintf(buf, "Asked for %s, allocated %lu bytes of %s, handle = %u.",
                memstr[stored_at], toallocate, memstr[use_this_type], handle);
        stopmsg(STOPMSG_INFO_ONLY | STOPMSG_NO_BUZZER, (char *)buf);
        DisplayMemory();
    }

    if (success)
        return (handle);
    else      // return 0 if failure
        return 0U;
}
Exemple #9
0
static int
pack_image(const char *indn, const char *outfn)
{
    struct imagewty_header *header;
    group_t *head, *filelist;
    uint32_t i, num_files;
    variable_t *var;
    FILE *cfp, *ofp;
    void *p;

    /* try to open image configuration */
    cfp = dir_fopen(indn, "image.cfg", "r");
    if (cfp == NULL) {
        fprintf(stderr, "Error: unable to open %s/%s!\n", indn, "image.cfg");
        return -ENOENT;
    }

    ofp = fopen(outfn, "wb");
    if (ofp == NULL) {
        fprintf(stderr, "Error: could not create image file %s!\n", outfn);
        fclose(cfp);
        return -ENOENT;
    }

    /* file is there, now try to load it */
    head = cfg_load(cfp);
    fclose(cfp);
    if (head == NULL) {
        fprintf(stderr, "Error: failed to parse %s/%s!\n", indn, "image.cfg");
        return -EINVAL;
    }

    /* Got configuration, time to start packing it all up! */
    var = cfg_find_var("filelist", head);
    if (var == NULL || var->type != VT_STRING) {
        fprintf(stderr, "Error: Unable to find filelist string "
                        "variable in configuration!\n");
        cfg_free(head);
        return -EINVAL;
    }

    filelist = cfg_find_group(var->str, head);
    if (filelist == NULL) {
        fprintf(stderr, "Error: unable to find group %s!\n", var->str);
        cfg_free(head);
        return -EINVAL;
    }

    num_files = cfg_count_vars(filelist);
    if (!num_files) {
        fprintf(stderr, "Error: no files to pack found in configuration!\n");
        cfg_free(head);
        return -EINVAL;
    }

    p = malloc(1024 + num_files * 1024);
    if (p == NULL) {
        fprintf(stderr, "Error: failed to allocate memory for image!\n");
        cfg_free(head);
        return -ENOMEM;
    }

    /* Initialize image file header */
    memset(p, 0, 1024 + num_files * 1024);
    header = p;
    memcpy(header->magic, IMAGEWTY_MAGIC, sizeof(header->magic));
    header->header_version = 0x0100;
    header->header_size = 0x50; /* should be 0x60 for version == 0x0300 */
    header->ram_base = 0x04D00000;
    header->version = cfg_get_number("version", head);
    header->image_size = 0; /* this will be filled in later on */
    header->image_header_size = 1024;
    header->v1.pid = cfg_get_number("pid", head);
    header->v1.vid = cfg_get_number("vid", head);
    header->v1.hardware_id = cfg_get_number("hardwareid", head);
    header->v1.firmware_id = cfg_get_number("firmwareid", head);
    header->v1.val1 = 1;
    header->v1.val1024 = 1024;
    header->v1.num_files = num_files;
    header->v1.num_files = cfg_count_vars(filelist);
    header->v1.val1024_2 = 1024;

    /* Setup file headers */
    {
        uint32_t offset = (num_files +1) * 1024;
        struct imagewty_file_header *fheaders;
        variable_t *var;

        fheaders = (struct imagewty_file_header*) (p + 1024);
        for(var=filelist->vars; var; var=var->next) {
            variable_t *v, *fn = NULL, *mt = NULL, *st = NULL;
            uint32_t size;
            FILE *fp;
            for (v=var->items; v; v=v->next) {
                if (v->type != VT_STRING)
                    continue;
                if (strcmp(v->name, "filename") == 0)
                    fn = v;
                else if (strcmp(v->name, "maintype") == 0)
                    mt = v;
                else if (strcmp(v->name, "subtype") == 0)
                    st = v;
            }

            if (!fn || !mt || !st) {
                fprintf(stderr, "Error: incomplete filelist item!\n");
                return -EINVAL;
            }

            fheaders->filename_len = IMAGEWTY_FHDR_FILENAME_LEN;
            fheaders->total_header_size = 1024;
            strcpy((char*)fheaders->v1.filename, fn->str);
            strcpy((char*)fheaders->maintype, mt->str);
            strcpy((char*)fheaders->subtype, st->str);

            fp = dir_fopen(indn, fn->str, "rb");
            if (fp) {
                fseek(fp, 0, SEEK_END);
                size = ftell(fp);
                fclose(fp);
            } else {
                fprintf(stderr, "Error: unable to read file '%s'!\n", fn->str);
                continue;
            }

            fheaders->v1.offset = offset;
            fheaders->v1.stored_length =
            fheaders->v1.original_length = size;
            if (fheaders->v1.stored_length & 0x1FF) {
                fheaders->v1.stored_length &= ~0x1FF;
                fheaders->v1.stored_length += 0x200;
            }
            offset += fheaders->v1.stored_length;
            fheaders = (struct imagewty_file_header*) ((uint8_t*)fheaders + 1024);
        }

        /* We now know the total size of the file; patch it into the main header */
        if (offset & 0xFF)
            offset = (offset & 0xFF) + 0x100;

        header->image_size = offset;
    }

    /* Now we have all headers setup in memory, time to write out the image file */
    fwrite(p, 1024, num_files +1, ofp);

    /* now write the file content too */
    for (i = 1; i <= num_files; i++) {
        struct imagewty_file_header *h =
            (struct imagewty_file_header*)(p + i * 1024);

        FILE *fp = dir_fopen(indn, h->v1.filename, "rb");
        if (fp != NULL) {
            char buf[512];
            size_t size = 0;
            while(!feof(fp)) {
                size_t bytesread = fread(buf, 1, 512, fp);
                if (bytesread) {
                    if (bytesread & 0x1ff)
                        bytesread = (bytesread & ~0x1ff) + 0x200;

                    if (flag_encryption_enabled)
                        rc6_encrypt_inplace(buf, bytesread, &filecontent_ctx);
                    fwrite(buf, 1, bytesread, ofp);
                }
                size += bytesread;
            }
            fclose(fp);
        }
    }

    /* Headers no longer used; encrypt and write if requested */
    if (flag_encryption_enabled) {
        void *curr = rc6_encrypt_inplace(p, 1024, &header_ctx);
        rc6_encrypt_inplace(curr, num_files * 1024, &fileheaders_ctx);
        rewind(ofp);
        fwrite(p, 1024, num_files +1, ofp);
    }

    fclose(ofp);

    /* Done, free configuration, no longer needed */
    cfg_free(head);

    return 0;
}