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