Search
lxdream.org :: lxdream/src/gdrom/gdi.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/gdrom/gdi.c
changeset 561:533f6b478071
prev498:10d5ba99a778
next644:ccae4bfa5f82
author nkeynes
date Fri Feb 08 11:30:04 2008 +0000 (16 years ago)
permissions -rw-r--r--
last change Bail out properly on read errors during a DMA cycle
view annotate diff log raw
     1 /**
     2  * $Id$
     3  *
     4  * NullDC GDI image format
     5  *
     6  * Copyright (c) 2005 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    19 #include <stdlib.h>
    20 #include <stdio.h>
    21 #include <stdint.h>
    22 #include <fcntl.h>
    23 #include <errno.h>
    24 #include <sys/stat.h>
    25 #include <glib/gutils.h>
    26 #include "gdrom/gdrom.h"
    29 static gboolean gdi_image_is_valid( FILE *f );
    30 static gdrom_disc_t gdi_image_open( const gchar *filename, FILE *f );
    32 struct gdrom_image_class gdi_image_class = { "NullDC GD-Rom Image", "gdi", 
    33 					     gdi_image_is_valid, gdi_image_open };
    35 static gboolean gdi_image_is_valid( FILE *f )
    36 {
    37     char line[512];
    38     uint32_t track_count;
    40     fseek(f, 0, SEEK_SET);
    41     if( fgets( line, sizeof(line), f ) == NULL ) {
    42 	return FALSE;
    43     }
    44     track_count = strtoul(line, NULL, 0);
    45     if( track_count == 0 || track_count > 99 ) {
    46 	return FALSE;
    47     }
    48     return TRUE;
    49 }
    51 static gdrom_disc_t gdi_image_open( const gchar *filename, FILE *f )
    52 {
    53     int i;
    54     uint32_t track_count;
    55     gdrom_disc_t disc;
    56     gdrom_image_t image;
    57     struct stat st;
    58     char line[512];
    59     gchar *dirname;
    61     fseek(f, 0, SEEK_SET);
    63     if( fgets( line, sizeof(line), f ) == NULL ) {
    64 	return FALSE;
    65     }
    66     track_count = strtoul(line, NULL, 0);
    67     if( track_count == 0 || track_count > 99 ) {
    68 	return NULL;
    69     }
    71     disc = gdrom_image_new(filename, f);
    72     if( disc == NULL ) {
    73 	ERROR("Unable to allocate memory!");
    74 	return NULL;
    75     }
    76     dirname = g_path_get_dirname(filename);
    77     image = (gdrom_image_t)disc;
    78     image->disc_type = IDE_DISC_GDROM;
    79     image->track_count = track_count;
    80     for( i=0; i<track_count; i++ ) {
    81 	int track_no, start_lba, flags, size, offset;
    82 	char filename[256];
    84 	if( fgets( line, sizeof(line), f ) == NULL ) {
    85 	    gdrom_image_destroy_no_close(disc);
    86 	    return NULL;
    87 	}
    88 	sscanf( line, "%d %d %d %d %s %d", &track_no, &start_lba, &flags, &size,
    89 		filename, &offset );
    90 	if( start_lba >= 45000 ) {
    91 	    image->track[i].session = 1;
    92 	} else {
    93 	    image->track[i].session = 0;
    94 	}
    95 	image->track[i].lba = start_lba + 150; // 2-second offset
    96 	image->track[i].flags = (flags & 0x0F)<<4;
    97 	image->track[i].sector_size = size;
    98 	if( strcasecmp( filename, "none" ) == 0 ) {
    99 	    image->track[i].file = NULL;
   100 	    image->track[i].sector_count = 0;
   101 	    image->track[i].mode = GDROM_MODE1;
   102 	} else {
   103 	    gchar *pathname = g_strdup_printf( "%s%c%s", dirname, G_DIR_SEPARATOR, filename );
   104 	    image->track[i].file = fopen( pathname, "ro" );
   105 	    g_free(pathname);
   106 	    if( image->track[i].file == NULL ) {
   107 		gdrom_image_destroy_no_close(disc);
   108 		g_free(dirname);
   109 		return NULL;
   110 	    }
   111 	    fstat( fileno(image->track[i].file), &st );
   112 	    image->track[i].sector_count = st.st_size / size;
   113 	    if( image->track[i].flags & TRACK_DATA ) {
   114 		/* Data track */
   115 		switch(size) {
   116 		case 2048: image->track[i].mode = GDROM_MODE1; break;
   117 		case 2336: image->track[i].mode = GDROM_GD; break;
   118 		case 2352: image->track[i].mode = GDROM_RAW; break;
   119 		default:
   120 		    gdrom_image_destroy_no_close(disc);
   121 		    g_free(dirname);
   122 		    return NULL;
   123 		}
   124 	    } else {
   125 		/* Audio track */
   126 		image->track[i].mode = GDROM_CDDA;
   127 		if( size != 2352 ) {
   128 		    gdrom_image_destroy_no_close(disc);
   129 		    g_free(dirname);
   130 		    return NULL;
   131 		}
   132 	    }
   133 	}
   134 	image->track[i].offset = offset;
   135     }
   136     g_free(dirname);
   137     return disc;
   138 }
.