nkeynes@342: nkeynes@138: /** nkeynes@561: * $Id$ nkeynes@138: * nkeynes@138: * GD-Rom access functions. nkeynes@138: * nkeynes@138: * Copyright (c) 2005 Nathan Keynes. nkeynes@138: * nkeynes@138: * This program is free software; you can redistribute it and/or modify nkeynes@138: * it under the terms of the GNU General Public License as published by nkeynes@138: * the Free Software Foundation; either version 2 of the License, or nkeynes@138: * (at your option) any later version. nkeynes@138: * nkeynes@138: * This program is distributed in the hope that it will be useful, nkeynes@138: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@138: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@138: * GNU General Public License for more details. nkeynes@138: */ nkeynes@138: nkeynes@138: #include nkeynes@237: #include nkeynes@168: #include nkeynes@678: #include nkeynes@138: #include "gdrom/ide.h" nkeynes@138: #include "gdrom/gdrom.h" nkeynes@678: #include "gdrom/gddriver.h" nkeynes@143: #include "gdrom/packet.h" nkeynes@138: #include "dream.h" nkeynes@138: nkeynes@342: extern gdrom_disc_t gdrom_disc; nkeynes@138: nkeynes@678: DEFINE_HOOK( gdrom_disc_change_hook, gdrom_disc_change_hook_t ) nkeynes@678: nkeynes@678: gdrom_fire_disc_changed( gdrom_disc_t disc ) nkeynes@678: { nkeynes@678: CALL_HOOKS( gdrom_disc_change_hook, disc, disc == NULL ? NULL : disc->name ); nkeynes@678: } nkeynes@678: nkeynes@492: gdrom_image_class_t gdrom_image_classes[] = { &cdrom_device_class, nkeynes@736: &nrg_image_class, nkeynes@736: &cdi_image_class, nkeynes@736: &gdi_image_class, nkeynes@736: NULL }; nkeynes@138: nkeynes@644: char *gdrom_mode_names[] = { "Mode 0", "Mode 1", "Mode 2", "Mode 2 Form 1", "Mode 2 Form 2", "Audio", nkeynes@736: "Mode 2 semiraw", "XA Raw", "Non-XA Raw" }; nkeynes@644: uint32_t gdrom_sector_size[] = { 0, 2048, 2336, 2048, 2324, 2352, 2336, 2352, 2352 }; nkeynes@138: nkeynes@709: gdrom_disc_t gdrom_image_open( const gchar *inFilename ) nkeynes@138: { nkeynes@709: const gchar *filename = inFilename; nkeynes@168: const gchar *ext = strrchr(filename, '.'); nkeynes@168: gdrom_disc_t disc = NULL; nkeynes@709: int fd; nkeynes@237: FILE *f; nkeynes@422: int i; nkeynes@168: gdrom_image_class_t extclz = NULL; nkeynes@168: nkeynes@709: // Check for a url-style filename. nkeynes@709: char *lizard_lips = strstr( filename, "://" ); nkeynes@709: if( lizard_lips != NULL ) { nkeynes@709: gchar *path = lizard_lips + 3; nkeynes@709: int method_len = (lizard_lips-filename); nkeynes@709: gchar method[method_len + 1]; nkeynes@709: memcpy( method, filename, method_len ); nkeynes@709: method[method_len] = '\0'; nkeynes@736: nkeynes@709: if( strcasecmp( method, "file" ) == 0 ) { nkeynes@709: filename = path; nkeynes@709: } else if( strcasecmp( method, "dvd" ) == 0 || nkeynes@709: strcasecmp( method, "cd" ) == 0 || nkeynes@709: strcasecmp( method, "cdrom" ) ) { nkeynes@709: return cdrom_open_device( method, path ); nkeynes@709: } else { nkeynes@709: ERROR( "Unrecognized URL method '%s' in filename '%s'", method, filename ); nkeynes@709: return NULL; nkeynes@709: } nkeynes@709: } nkeynes@736: nkeynes@709: fd = open( filename, O_RDONLY | O_NONBLOCK ); nkeynes@237: if( fd == -1 ) { nkeynes@709: return NULL; nkeynes@168: } nkeynes@168: nkeynes@237: f = fdopen(fd, "ro"); nkeynes@237: nkeynes@237: nkeynes@168: /* try extensions */ nkeynes@168: if( ext != NULL ) { nkeynes@736: ext++; /* Skip the '.' */ nkeynes@736: for( i=0; gdrom_image_classes[i] != NULL; i++ ) { nkeynes@736: if( gdrom_image_classes[i]->extension != NULL && nkeynes@736: strcasecmp( gdrom_image_classes[i]->extension, ext ) == 0 ) { nkeynes@736: extclz = gdrom_image_classes[i]; nkeynes@736: if( extclz->is_valid_file(f) ) { nkeynes@736: disc = extclz->open_image_file(filename, f); nkeynes@736: if( disc != NULL ) nkeynes@736: return disc; nkeynes@736: } nkeynes@736: break; nkeynes@736: } nkeynes@736: } nkeynes@168: } nkeynes@168: nkeynes@168: /* Okay, fall back to magic */ nkeynes@237: gboolean recognized = FALSE; nkeynes@168: for( i=0; gdrom_image_classes[i] != NULL; i++ ) { nkeynes@736: if( gdrom_image_classes[i] != extclz && nkeynes@736: gdrom_image_classes[i]->is_valid_file(f) ) { nkeynes@736: recognized = TRUE; nkeynes@736: disc = gdrom_image_classes[i]->open_image_file(filename, f); nkeynes@736: if( disc != NULL ) nkeynes@736: return disc; nkeynes@736: } nkeynes@168: } nkeynes@168: nkeynes@168: fclose(f); nkeynes@168: return NULL; nkeynes@138: } nkeynes@138: nkeynes@138: void gdrom_mount_disc( gdrom_disc_t disc ) nkeynes@138: { nkeynes@678: if( disc != gdrom_disc ) { nkeynes@695: if( gdrom_disc != NULL ) { nkeynes@695: gdrom_disc->close(gdrom_disc); nkeynes@695: } nkeynes@678: gdrom_disc = disc; nkeynes@678: gdrom_image_dump_info( disc ); nkeynes@678: gdrom_fire_disc_changed( disc ); nkeynes@678: } nkeynes@138: } nkeynes@138: nkeynes@433: gboolean gdrom_mount_image( const gchar *filename ) nkeynes@138: { nkeynes@138: gdrom_disc_t disc = gdrom_image_open(filename); nkeynes@695: if( disc != NULL ) { nkeynes@678: gdrom_mount_disc( disc ); nkeynes@678: return TRUE; nkeynes@433: } nkeynes@433: return FALSE; nkeynes@138: } nkeynes@138: nkeynes@138: void gdrom_unmount_disc( ) nkeynes@138: { nkeynes@138: if( gdrom_disc != NULL ) { nkeynes@678: gdrom_disc->close(gdrom_disc); nkeynes@678: gdrom_fire_disc_changed(NULL); nkeynes@691: gdrom_disc = NULL; nkeynes@138: } nkeynes@138: } nkeynes@138: nkeynes@464: gdrom_disc_t gdrom_get_current_disc() nkeynes@464: { nkeynes@464: return gdrom_disc; nkeynes@464: } nkeynes@613: nkeynes@678: const gchar *gdrom_get_current_disc_name() nkeynes@678: { nkeynes@678: if( gdrom_disc == NULL ) { nkeynes@678: return NULL; nkeynes@678: } else { nkeynes@678: return gdrom_disc->name; nkeynes@678: } nkeynes@678: } nkeynes@678: nkeynes@613: gchar *gdrom_get_relative_filename( const gchar *base_name, const gchar *rel_name ) nkeynes@613: { nkeynes@613: gchar *dirname = g_path_get_dirname(base_name); nkeynes@613: gchar *pathname = g_strdup_printf( "%s%c%s", dirname, G_DIR_SEPARATOR, rel_name ); nkeynes@613: g_free(dirname); nkeynes@613: return pathname; nkeynes@613: }