From 379a8879f7dae1a9074317c0270e12dd203b32c0 Mon Sep 17 00:00:00 2001 From: "SND\\weimingzhi_cp" Date: Sun, 13 Mar 2011 08:26:16 +0000 Subject: Temporarily reverted r64524 until I (or someone else) find the time to sort out the stuff. git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@64536 e17a0e51-4ae3-4d35-97c3-1a29b211df97 --- plugins/dfcdrom/cdr.c | 1056 +++++++++++++++++------------------ plugins/dfcdrom/cdr.h | 405 +++++++------- plugins/dfcdrom/cdrcfg-0.1df/main.c | 580 +++++++++---------- plugins/dfcdrom/cfg.c | 200 ++++--- 4 files changed, 1133 insertions(+), 1108 deletions(-) (limited to 'plugins/dfcdrom') diff --git a/plugins/dfcdrom/cdr.c b/plugins/dfcdrom/cdr.c index cf0a539c..ab61886e 100644 --- a/plugins/dfcdrom/cdr.c +++ b/plugins/dfcdrom/cdr.c @@ -1,528 +1,528 @@ -/* - * Copyright (c) 2010, Wei Mingzhi . - * All Rights Reserved. - * - * Based on: Cdrom for Psemu Pro like Emulators - * By: linuzappz - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include "cdr.h" - -#ifndef USE_NULL -static char *LibName = N_("CD-ROM Drive Reader"); -#else -static char *LibName = N_("CDR NULL Plugin"); -#endif - -int initial_time = 0; - -pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; -pthread_cond_t cond = PTHREAD_COND_INITIALIZER; - -volatile CacheData *cdcache; -volatile int cacheaddr; - -volatile unsigned char *cdbuffer; - -crdata cr; - -unsigned char lastTime[3]; -pthread_t thread; -int subqread; -volatile int stopth, found, locked, playing; - -long (*ReadTrackT[])() = { - ReadNormal, - ReadThreaded, -}; - -unsigned char* (*GetBufferT[])() = { - GetBNormal, - GetBThreaded, -}; - -long (*fReadTrack)(); -unsigned char* (*fGetBuffer)(); - -void *CdrThread(void *arg); - -long CDRinit(void) { - thread = (pthread_t)-1; - return 0; -} - -long CDRshutdown(void) { - return 0; -} - -long CDRopen(void) { - LoadConf(); - -#ifndef _MACOSX - if (IsCdHandleOpen()) - return 0; // it's already open -#endif - - if (OpenCdHandle(CdromDev) == -1) { // if we can't open the cdrom we'll works as a null plugin - fprintf(stderr, "CDR: Could not open %s\n", CdromDev); - } - - fReadTrack = ReadTrackT[ReadMode]; - fGetBuffer = GetBufferT[ReadMode]; - - if (ReadMode == THREADED) { - cdcache = (CacheData *)malloc(CacheSize * sizeof(CacheData)); - if (cdcache == NULL) return -1; - memset((void *)cdcache, 0, CacheSize * sizeof(CacheData)); - - found = 0; - } else { - cdbuffer = cr.buf + 12; /* skip sync data */ - } - - if (ReadMode == THREADED) { - pthread_attr_t attr; - - pthread_mutex_init(&mut, NULL); - pthread_cond_init(&cond, NULL); - locked = 0; - - pthread_attr_init(&attr); - pthread_create(&thread, &attr, CdrThread, NULL); - - cacheaddr = -1; - } else thread = (pthread_t)-1; - - playing = 0; - stopth = 0; - initial_time = 0; - - return 0; -} - -long CDRclose(void) { - if (!IsCdHandleOpen()) return 0; - - if (playing) CDRstop(); - - CloseCdHandle(); - - if (thread != (pthread_t)-1) { - if (locked == 0) { - stopth = 1; - while (locked == 0) usleep(5000); - } - - stopth = 2; - pthread_mutex_lock(&mut); - pthread_cond_signal(&cond); - pthread_mutex_unlock(&mut); - - pthread_join(thread, NULL); - pthread_mutex_destroy(&mut); - pthread_cond_destroy(&cond); - } - - if (ReadMode == THREADED) { - free((void *)cdcache); - } - - return 0; -} - -// return Starting and Ending Track -// buffer: -// byte 0 - start track -// byte 1 - end track -long CDRgetTN(unsigned char *buffer) { - long ret; - - if (!IsCdHandleOpen()) { - buffer[0] = 1; - buffer[1] = 1; - return 0; - } - - if (ReadMode == THREADED) pthread_mutex_lock(&mut); - ret = GetTN(buffer); - if (ReadMode == THREADED) pthread_mutex_unlock(&mut); - - return ret; -} - -// return Track Time -// buffer: -// byte 0 - frame -// byte 1 - second -// byte 2 - minute -long CDRgetTD(unsigned char track, unsigned char *buffer) { - long ret; - - if (!IsCdHandleOpen()) { - memset(buffer + 1, 0, 3); - return 0; - } - - if (ReadMode == THREADED) pthread_mutex_lock(&mut); - ret = GetTD(track, buffer); - if (ReadMode == THREADED) pthread_mutex_unlock(&mut); - - return ret; -} - -// normal reading -long ReadNormal() { - if (ReadSector(&cr) == -1) - return -1; - - return 0; -} - -unsigned char *GetBNormal() { - return (unsigned char *)cdbuffer; -} - -// threaded reading (with cache) -long ReadThreaded() { - int addr = msf_to_lba(cr.msf.cdmsf_min0, cr.msf.cdmsf_sec0, cr.msf.cdmsf_frame0); - int i; - - if (addr >= cacheaddr && addr < (cacheaddr + CacheSize) && cacheaddr != -1) { - i = addr - cacheaddr; - PRINTF("found %d\n", (addr - cacheaddr)); - cdbuffer = cdcache[i].cr.buf + 12; - while (cdcache[i].msf[0] != cr.msf.cdmsf_min0 || - cdcache[i].msf[1] != cr.msf.cdmsf_sec0 || - cdcache[i].msf[2] != cr.msf.cdmsf_frame0) { - if (locked == 1) { - if (cdcache[i].ret == 0) break; - return -1; - } - usleep(5000); - } - PRINTF("%d:%d:%d, %p, %p\n", cdcache[i].msf[0], cdcache[i].msf[1], cdcache[i].msf[2], cdbuffer, cdcache); - found = 1; - - return 0; - } else found = 0; - - if (locked == 0) { - stopth = 1; - while (locked == 0) { usleep(5000); } - stopth = 0; - } - - // not found in cache - locked = 0; - - pthread_mutex_lock(&mut); - pthread_cond_signal(&cond); - pthread_mutex_unlock(&mut); - - return 0; -} - -unsigned char *GetBThreaded() { - PRINTF("threadc %d\n", found); - - if (found == 1) return (unsigned char *)cdbuffer; - - cdbuffer = cdcache[0].cr.buf + 12; - - while (cdcache[0].msf[0] != cr.msf.cdmsf_min0 || - cdcache[0].msf[1] != cr.msf.cdmsf_sec0 || - cdcache[0].msf[2] != cr.msf.cdmsf_frame0) { - if (locked == 1) return NULL; - usleep(5000); - } - if (cdcache[0].ret == -1) return NULL; - - return (unsigned char *)cdbuffer; -} - -void *CdrThread(void *arg) { - unsigned char curTime[3]; - int i; - - for (;;) { - pthread_mutex_lock(&mut); - locked = 1; - - pthread_cond_wait(&cond, &mut); - - if (stopth == 2) pthread_exit(NULL); - // refill the buffer - cacheaddr = msf_to_lba(cr.msf.cdmsf_min0, cr.msf.cdmsf_sec0, cr.msf.cdmsf_frame0); - - memcpy(curTime, &cr.msf, 3); - - PRINTF("start thc %d:%d:%d\n", curTime[0], curTime[1], curTime[2]); - - for (i = 0; i < CacheSize; i++) { - cdcache[i].cr.msf.cdmsf_min0 = curTime[0]; - cdcache[i].cr.msf.cdmsf_sec0 = curTime[1]; - cdcache[i].cr.msf.cdmsf_frame0 = curTime[2]; - - PRINTF("reading %d:%d:%d\n", curTime[0], curTime[1], curTime[2]); - - cdcache[i].ret = ReadSector((crdata *)&cdcache[i].cr); - if (cdcache[i].ret == -1) break; - - PRINTF("readed %x:%x:%x\n", cdcache[i].cr.buf[12], cdcache[i].cr.buf[13], cdcache[i].cr.buf[14]); - - cdcache[i].msf[0] = curTime[0]; - cdcache[i].msf[1] = curTime[1]; - cdcache[i].msf[2] = curTime[2]; - - curTime[2]++; - if (curTime[2] == 75) { - curTime[2] = 0; - curTime[1]++; - if (curTime[1] == 60) { - curTime[1] = 0; - curTime[0]++; - } - } - - if (stopth) break; - } - - pthread_mutex_unlock(&mut); - } - - return NULL; -} - -// read track -// time: -// byte 0 - minute -// byte 1 - second -// byte 2 - frame -// uses bcd format -long CDRreadTrack(unsigned char *time) { - if (!IsCdHandleOpen()) { - memset(cr.buf, 0, DATA_SIZE); - return 0; - } - - PRINTF("CDRreadTrack %d:%d:%d\n", btoi(time[0]), btoi(time[1]), btoi(time[2])); - - if (UseSubQ) memcpy(lastTime, time, 3); - subqread = 0; - - cr.msf.cdmsf_min0 = btoi(time[0]); - cr.msf.cdmsf_sec0 = btoi(time[1]); - cr.msf.cdmsf_frame0 = btoi(time[2]); - - return fReadTrack(); -} - -// return readed track -unsigned char *CDRgetBuffer(void) { - return fGetBuffer(); -} - -// plays cdda audio -// sector: -// byte 0 - minute -// byte 1 - second -// byte 2 - frame -// does NOT uses bcd format -long CDRplay(unsigned char *sector) { - long ret; - - if (!IsCdHandleOpen()) - return 0; - - // If play was called with the same time as the previous call, - // don't restart it. Of course, if play is called with a different - // track, stop playing the current stream. - if (playing) { - if (msf_to_lba(sector[0], sector[1], sector[2]) == initial_time) - return 0; - else - CDRstop(); - } - - initial_time = msf_to_lba(sector[0], sector[1], sector[2]); - - if (ReadMode == THREADED) pthread_mutex_lock(&mut); - ret = PlayCDDA(sector); - if (ReadMode == THREADED) pthread_mutex_unlock(&mut); - - if (ret == 0) { - playing = 1; - return 0; - } - - return -1; -} - -// stops cdda audio -long CDRstop(void) { - long ret; - - if (!IsCdHandleOpen()) - return 0; - - if (ReadMode == THREADED) pthread_mutex_lock(&mut); - ret = StopCDDA(); - if (ReadMode == THREADED) pthread_mutex_unlock(&mut); - - if (ret == 0) { - playing = 0; - initial_time = 0; - - return 0; - } - - return -1; -} - -// reads cdr status -// type: -// 0x00 - unknown -// 0x01 - data -// 0x02 - audio -// 0xff - no cdrom -// status: (only shell open supported) -// 0x00 - unknown -// 0x01 - error -// 0x04 - seek error -// 0x10 - shell open -// 0x20 - reading -// 0x40 - seeking -// 0x80 - playing -// time: -// byte 0 - minute -// byte 1 - second -// byte 2 - frame - -long CDRgetStatus(struct CdrStat *stat) { - long ret; - - if (!IsCdHandleOpen()) - return -1; - - if (ReadMode == THREADED) pthread_mutex_lock(&mut); - ret = GetStatus(playing, stat); - if (ReadMode == THREADED) pthread_mutex_unlock(&mut); - - return ret; -} - -unsigned char *CDRgetBufferSub(void) { - static unsigned char *p = NULL; - - if (!UseSubQ) return NULL; - if (subqread) return p; - - if (ReadMode == THREADED) pthread_mutex_lock(&mut); - p = ReadSub(lastTime); - if (ReadMode == THREADED) pthread_mutex_unlock(&mut); - - if (p != NULL) subqread = 1; - - return p; -} - -// read CDDA sector into buffer -long CDRreadCDDA(unsigned char m, unsigned char s, unsigned char f, unsigned char *buffer) { - unsigned char msf[3] = {m, s, f}; - unsigned char *p; - - if (CDRreadTrack(msf) != 0) return -1; - - p = CDRgetBuffer(); - if (p == NULL) return -1; - - memcpy(buffer, p - 12, CD_FRAMESIZE_RAW); // copy from the beginning of the sector - return 0; -} - -// get Track End Time -long CDRgetTE(unsigned char track, unsigned char *m, unsigned char *s, unsigned char *f) { - long ret; - - if (!IsCdHandleOpen()) return -1; - - if (ReadMode == THREADED) pthread_mutex_lock(&mut); - ret = GetTE(track, m, s, f); - if (ReadMode == THREADED) pthread_mutex_unlock(&mut); - - return ret; -} - -#ifndef _MACOSX - -static void ExecCfg(char *arg) { - char cfg[256]; - struct stat buf; - - strcpy(cfg, "./cfgDFCdrom"); - if (stat(cfg, &buf) != -1) { - if (fork() == 0) { - execl(cfg, "cfgDFCdrom", arg, NULL); - exit(0); - } - return; - } - - strcpy(cfg, "./cfg/DFCdrom"); - if (stat(cfg, &buf) != -1) { - if (fork() == 0) { - execl(cfg, "cfgDFCdrom", arg, NULL); - exit(0); - } - return; - } - - fprintf(stderr, "cfgDFCdrom file not found!\n"); -} - -long CDRconfigure() { -#ifndef USE_NULL - ExecCfg("configure"); -#endif - return 0; -} - -void CDRabout() { - ExecCfg("about"); -} - -#endif - -long CDRtest(void) { -#ifndef USE_NULL - if (OpenCdHandle(CdromDev) == -1) - return -1; - CloseCdHandle(); -#endif - return 0; -} - -char *PSEgetLibName(void) { - return _(LibName); -} - -unsigned long PSEgetLibType(void) { - return PSE_LT_CDR; -} - -unsigned long PSEgetLibVersion(void) { - return 1 << 16; -} +/* + * Copyright (c) 2010, Wei Mingzhi . + * All Rights Reserved. + * + * Based on: Cdrom for Psemu Pro like Emulators + * By: linuzappz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "cdr.h" + +#ifndef USE_NULL +static char *LibName = N_("CD-ROM Drive Reader"); +#else +static char *LibName = N_("CDR NULL Plugin"); +#endif + +int initial_time = 0; + +pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + +volatile CacheData *cdcache; +volatile int cacheaddr; + +volatile unsigned char *cdbuffer; + +crdata cr; + +unsigned char lastTime[3]; +pthread_t thread; +int subqread; +volatile int stopth, found, locked, playing; + +long (*ReadTrackT[])() = { + ReadNormal, + ReadThreaded, +}; + +unsigned char* (*GetBufferT[])() = { + GetBNormal, + GetBThreaded, +}; + +long (*fReadTrack)(); +unsigned char* (*fGetBuffer)(); + +void *CdrThread(void *arg); + +long CDRinit(void) { + thread = (pthread_t)-1; + return 0; +} + +long CDRshutdown(void) { + return 0; +} + +long CDRopen(void) { + LoadConf(); + +#ifndef _MACOSX + if (IsCdHandleOpen()) + return 0; // it's already open +#endif + + if (OpenCdHandle(CdromDev) == -1) { // if we can't open the cdrom we'll works as a null plugin + fprintf(stderr, "CDR: Could not open %s\n", CdromDev); + } + + fReadTrack = ReadTrackT[ReadMode]; + fGetBuffer = GetBufferT[ReadMode]; + + if (ReadMode == THREADED) { + cdcache = (CacheData *)malloc(CacheSize * sizeof(CacheData)); + if (cdcache == NULL) return -1; + memset((void *)cdcache, 0, CacheSize * sizeof(CacheData)); + + found = 0; + } else { + cdbuffer = cr.buf + 12; /* skip sync data */ + } + + if (ReadMode == THREADED) { + pthread_attr_t attr; + + pthread_mutex_init(&mut, NULL); + pthread_cond_init(&cond, NULL); + locked = 0; + + pthread_attr_init(&attr); + pthread_create(&thread, &attr, CdrThread, NULL); + + cacheaddr = -1; + } else thread = (pthread_t)-1; + + playing = 0; + stopth = 0; + initial_time = 0; + + return 0; +} + +long CDRclose(void) { + if (!IsCdHandleOpen()) return 0; + + if (playing) CDRstop(); + + CloseCdHandle(); + + if (thread != (pthread_t)-1) { + if (locked == 0) { + stopth = 1; + while (locked == 0) usleep(5000); + } + + stopth = 2; + pthread_mutex_lock(&mut); + pthread_cond_signal(&cond); + pthread_mutex_unlock(&mut); + + pthread_join(thread, NULL); + pthread_mutex_destroy(&mut); + pthread_cond_destroy(&cond); + } + + if (ReadMode == THREADED) { + free((void *)cdcache); + } + + return 0; +} + +// return Starting and Ending Track +// buffer: +// byte 0 - start track +// byte 1 - end track +long CDRgetTN(unsigned char *buffer) { + long ret; + + if (!IsCdHandleOpen()) { + buffer[0] = 1; + buffer[1] = 1; + return 0; + } + + if (ReadMode == THREADED) pthread_mutex_lock(&mut); + ret = GetTN(buffer); + if (ReadMode == THREADED) pthread_mutex_unlock(&mut); + + return ret; +} + +// return Track Time +// buffer: +// byte 0 - frame +// byte 1 - second +// byte 2 - minute +long CDRgetTD(unsigned char track, unsigned char *buffer) { + long ret; + + if (!IsCdHandleOpen()) { + memset(buffer + 1, 0, 3); + return 0; + } + + if (ReadMode == THREADED) pthread_mutex_lock(&mut); + ret = GetTD(track, buffer); + if (ReadMode == THREADED) pthread_mutex_unlock(&mut); + + return ret; +} + +// normal reading +long ReadNormal() { + if (ReadSector(&cr) == -1) + return -1; + + return 0; +} + +unsigned char *GetBNormal() { + return (unsigned char *)cdbuffer; +} + +// threaded reading (with cache) +long ReadThreaded() { + int addr = msf_to_lba(cr.msf.cdmsf_min0, cr.msf.cdmsf_sec0, cr.msf.cdmsf_frame0); + int i; + + if (addr >= cacheaddr && addr < (cacheaddr + CacheSize) && cacheaddr != -1) { + i = addr - cacheaddr; + PRINTF("found %d\n", (addr - cacheaddr)); + cdbuffer = cdcache[i].cr.buf + 12; + while (cdcache[i].msf[0] != cr.msf.cdmsf_min0 || + cdcache[i].msf[1] != cr.msf.cdmsf_sec0 || + cdcache[i].msf[2] != cr.msf.cdmsf_frame0) { + if (locked == 1) { + if (cdcache[i].ret == 0) break; + return -1; + } + usleep(5000); + } + PRINTF("%d:%d:%d, %p, %p\n", cdcache[i].msf[0], cdcache[i].msf[1], cdcache[i].msf[2], cdbuffer, cdcache); + found = 1; + + return 0; + } else found = 0; + + if (locked == 0) { + stopth = 1; + while (locked == 0) { usleep(5000); } + stopth = 0; + } + + // not found in cache + locked = 0; + + pthread_mutex_lock(&mut); + pthread_cond_signal(&cond); + pthread_mutex_unlock(&mut); + + return 0; +} + +unsigned char *GetBThreaded() { + PRINTF("threadc %d\n", found); + + if (found == 1) return (unsigned char *)cdbuffer; + + cdbuffer = cdcache[0].cr.buf + 12; + + while (cdcache[0].msf[0] != cr.msf.cdmsf_min0 || + cdcache[0].msf[1] != cr.msf.cdmsf_sec0 || + cdcache[0].msf[2] != cr.msf.cdmsf_frame0) { + if (locked == 1) return NULL; + usleep(5000); + } + if (cdcache[0].ret == -1) return NULL; + + return (unsigned char *)cdbuffer; +} + +void *CdrThread(void *arg) { + unsigned char curTime[3]; + int i; + + for (;;) { + pthread_mutex_lock(&mut); + locked = 1; + + pthread_cond_wait(&cond, &mut); + + if (stopth == 2) pthread_exit(NULL); + // refill the buffer + cacheaddr = msf_to_lba(cr.msf.cdmsf_min0, cr.msf.cdmsf_sec0, cr.msf.cdmsf_frame0); + + memcpy(curTime, &cr.msf, 3); + + PRINTF("start thc %d:%d:%d\n", curTime[0], curTime[1], curTime[2]); + + for (i = 0; i < CacheSize; i++) { + cdcache[i].cr.msf.cdmsf_min0 = curTime[0]; + cdcache[i].cr.msf.cdmsf_sec0 = curTime[1]; + cdcache[i].cr.msf.cdmsf_frame0 = curTime[2]; + + PRINTF("reading %d:%d:%d\n", curTime[0], curTime[1], curTime[2]); + + cdcache[i].ret = ReadSector((crdata *)&cdcache[i].cr); + if (cdcache[i].ret == -1) break; + + PRINTF("readed %x:%x:%x\n", cdcache[i].cr.buf[12], cdcache[i].cr.buf[13], cdcache[i].cr.buf[14]); + + cdcache[i].msf[0] = curTime[0]; + cdcache[i].msf[1] = curTime[1]; + cdcache[i].msf[2] = curTime[2]; + + curTime[2]++; + if (curTime[2] == 75) { + curTime[2] = 0; + curTime[1]++; + if (curTime[1] == 60) { + curTime[1] = 0; + curTime[0]++; + } + } + + if (stopth) break; + } + + pthread_mutex_unlock(&mut); + } + + return NULL; +} + +// read track +// time: +// byte 0 - minute +// byte 1 - second +// byte 2 - frame +// uses bcd format +long CDRreadTrack(unsigned char *time) { + if (!IsCdHandleOpen()) { + memset(cr.buf, 0, DATA_SIZE); + return 0; + } + + PRINTF("CDRreadTrack %d:%d:%d\n", btoi(time[0]), btoi(time[1]), btoi(time[2])); + + if (UseSubQ) memcpy(lastTime, time, 3); + subqread = 0; + + cr.msf.cdmsf_min0 = btoi(time[0]); + cr.msf.cdmsf_sec0 = btoi(time[1]); + cr.msf.cdmsf_frame0 = btoi(time[2]); + + return fReadTrack(); +} + +// return readed track +unsigned char *CDRgetBuffer(void) { + return fGetBuffer(); +} + +// plays cdda audio +// sector: +// byte 0 - minute +// byte 1 - second +// byte 2 - frame +// does NOT uses bcd format +long CDRplay(unsigned char *sector) { + long ret; + + if (!IsCdHandleOpen()) + return 0; + + // If play was called with the same time as the previous call, + // don't restart it. Of course, if play is called with a different + // track, stop playing the current stream. + if (playing) { + if (msf_to_lba(sector[0], sector[1], sector[2]) == initial_time) + return 0; + else + CDRstop(); + } + + initial_time = msf_to_lba(sector[0], sector[1], sector[2]); + + if (ReadMode == THREADED) pthread_mutex_lock(&mut); + ret = PlayCDDA(sector); + if (ReadMode == THREADED) pthread_mutex_unlock(&mut); + + if (ret == 0) { + playing = 1; + return 0; + } + + return -1; +} + +// stops cdda audio +long CDRstop(void) { + long ret; + + if (!IsCdHandleOpen()) + return 0; + + if (ReadMode == THREADED) pthread_mutex_lock(&mut); + ret = StopCDDA(); + if (ReadMode == THREADED) pthread_mutex_unlock(&mut); + + if (ret == 0) { + playing = 0; + initial_time = 0; + + return 0; + } + + return -1; +} + +// reads cdr status +// type: +// 0x00 - unknown +// 0x01 - data +// 0x02 - audio +// 0xff - no cdrom +// status: (only shell open supported) +// 0x00 - unknown +// 0x01 - error +// 0x04 - seek error +// 0x10 - shell open +// 0x20 - reading +// 0x40 - seeking +// 0x80 - playing +// time: +// byte 0 - minute +// byte 1 - second +// byte 2 - frame + +long CDRgetStatus(struct CdrStat *stat) { + long ret; + + if (!IsCdHandleOpen()) + return -1; + + if (ReadMode == THREADED) pthread_mutex_lock(&mut); + ret = GetStatus(playing, stat); + if (ReadMode == THREADED) pthread_mutex_unlock(&mut); + + return ret; +} + +unsigned char *CDRgetBufferSub(void) { + static unsigned char *p = NULL; + + if (!UseSubQ) return NULL; + if (subqread) return p; + + if (ReadMode == THREADED) pthread_mutex_lock(&mut); + p = ReadSub(lastTime); + if (ReadMode == THREADED) pthread_mutex_unlock(&mut); + + if (p != NULL) subqread = 1; + + return p; +} + +// read CDDA sector into buffer +long CDRreadCDDA(unsigned char m, unsigned char s, unsigned char f, unsigned char *buffer) { + unsigned char msf[3] = {m, s, f}; + unsigned char *p; + + if (CDRreadTrack(msf) != 0) return -1; + + p = CDRgetBuffer(); + if (p == NULL) return -1; + + memcpy(buffer, p - 12, CD_FRAMESIZE_RAW); // copy from the beginning of the sector + return 0; +} + +// get Track End Time +long CDRgetTE(unsigned char track, unsigned char *m, unsigned char *s, unsigned char *f) { + long ret; + + if (!IsCdHandleOpen()) return -1; + + if (ReadMode == THREADED) pthread_mutex_lock(&mut); + ret = GetTE(track, m, s, f); + if (ReadMode == THREADED) pthread_mutex_unlock(&mut); + + return ret; +} + +#ifndef _MACOSX + +void ExecCfg(char *arg) { + char cfg[256]; + struct stat buf; + + strcpy(cfg, "./cfgDFCdrom"); + if (stat(cfg, &buf) != -1) { + if (fork() == 0) { + execl(cfg, "cfgDFCdrom", arg, NULL); + exit(0); + } + return; + } + + strcpy(cfg, "./cfg/DFCdrom"); + if (stat(cfg, &buf) != -1) { + if (fork() == 0) { + execl(cfg, "cfgDFCdrom", arg, NULL); + exit(0); + } + return; + } + + fprintf(stderr, "cfgDFCdrom file not found!\n"); +} + +long CDRconfigure() { +#ifndef USE_NULL + ExecCfg("configure"); +#endif + return 0; +} + +void CDRabout() { + ExecCfg("about"); +} + +#endif + +long CDRtest(void) { +#ifndef USE_NULL + if (OpenCdHandle(CdromDev) == -1) + return -1; + CloseCdHandle(); +#endif + return 0; +} + +char *PSEgetLibName(void) { + return _(LibName); +} + +unsigned long PSEgetLibType(void) { + return PSE_LT_CDR; +} + +unsigned long PSEgetLibVersion(void) { + return 1 << 16; +} diff --git a/plugins/dfcdrom/cdr.h b/plugins/dfcdrom/cdr.h index 928683d3..771faa77 100644 --- a/plugins/dfcdrom/cdr.h +++ b/plugins/dfcdrom/cdr.h @@ -1,189 +1,216 @@ -/* - * Copyright (c) 2010, Wei Mingzhi . - * All Rights Reserved. - * - * Based on: Cdrom for Psemu Pro like Emulators - * By: linuzappz - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#ifndef __CDR_H__ -#define __CDR_H__ - -//#define DEBUG 1 - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "psemu_plugin_defs.h" - -#if defined (__linux__) - -#include -#include -#include - -#ifndef CDROMSETSPINDOWN -#define CDROMSETSPINDOWN 0x531e -#endif - -#define DEV_DEF "/dev/cdrom" - -#else - -struct cdrom_msf { - unsigned char cdmsf_min0; /* start minute */ - unsigned char cdmsf_sec0; /* start second */ - unsigned char cdmsf_frame0; /* start frame */ - unsigned char cdmsf_min1; /* end minute */ - unsigned char cdmsf_sec1; /* end second */ - unsigned char cdmsf_frame1; /* end frame */ -}; - -#define CD_SECS 60 -#define CD_FRAMES 75 -#define CD_MSF_OFFSET 150 -#define CD_FRAMESIZE_SUB 96 - -#if defined (__FreeBSD__) -#define DEV_DEF "/dev/cd0" -#else -#define DEV_DEF "" -#endif - -#if !defined (USE_LIBCDIO) && !defined (_MACOSX) -#define USE_NULL 1 -#endif - -#endif - -extern char CdromDev[256]; -extern long ReadMode; -extern long UseSubQ; -extern long CacheSize; -extern long CdrSpeed; -extern long SpinDown; - -#define NORMAL 0 -#define THREADED 1 -#define READ_MODES 2 - -#ifndef CD_FRAMESIZE_RAW -#define CD_FRAMESIZE_RAW 2352 -#endif - -#define DATA_SIZE (CD_FRAMESIZE_RAW - 12) - -// spindown codes -#define SPINDOWN_VENDOR_SPECIFIC 0x00 -#define SPINDOWN_125MS 0x01 -#define SPINDOWN_250MS 0x02 -#define SPINDOWN_500MS 0x03 -#define SPINDOWN_1S 0x04 -#define SPINDOWN_2S 0x05 -#define SPINDOWN_4S 0x06 -#define SPINDOWN_8S 0x07 -#define SPINDOWN_16S 0x08 -#define SPINDOWN_32S 0x09 -#define SPINDOWN_1MIN 0x0A -#define SPINDOWN_2MIN 0x0B -#define SPINDOWN_4MIN 0x0C -#define SPINDOWN_8MIN 0x0D -#define SPINDOWN_16MIN 0x0E -#define SPINDOWN_32MIN 0x0F - -typedef struct _MMC_READ_CD { - unsigned char Code; // 0xBE - - unsigned char RelativeAddress : 1; - unsigned char : 1; - unsigned char ExpectedSectorType : 3; - unsigned char Lun : 3; - - unsigned char StartingLBA[4]; - unsigned char TransferBlocks[3]; - - unsigned char : 1; - unsigned char ErrorFlags : 2; - unsigned char IncludeEDC : 1; - unsigned char IncludeUserData : 1; - unsigned char HeaderCode : 2; - unsigned char IncludeSyncData : 1; - - unsigned char SubChannelSelection : 3; - unsigned char : 5; - - unsigned char Ctrl; -} MMC_READ_CD; - -#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ -#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ - -typedef union { - struct cdrom_msf msf; - unsigned char buf[CD_FRAMESIZE_RAW]; -} crdata; - -typedef struct { - unsigned char msf[3]; - crdata cr; - int ret; -} CacheData; - -long ReadNormal(); -long ReadThreaded(); -unsigned char* GetBNormal(); -unsigned char* GetBThreaded(); - -long CDRstop(void); - -void LoadConf(); -void SaveConf(); - -#ifdef DEBUG -#define PRINTF printf -#else -#define PRINTF(...) /* */ -#endif - -unsigned int msf_to_lba(char m, char s, char f); -void lba_to_msf(unsigned int s, unsigned char *msf); -void DecodeRawSubData(unsigned char *subbuffer); -unsigned short calcCrc(unsigned char *d, int len); - -int OpenCdHandle(); -void CloseCdHandle(); -int IsCdHandleOpen(); -long GetTN(unsigned char *buffer); -long GetTD(unsigned char track, unsigned char *buffer); -long GetTE(unsigned char track, unsigned char *m, unsigned char *s, unsigned char *f); -long ReadSector(crdata *cr); -long PlayCDDA(unsigned char *sector); -long StopCDDA(); -#include "psemu_plugin_defs.h" -long GetStatus(int playing, struct CdrStat *stat); -unsigned char *ReadSub(const unsigned char *time); - -#endif +/* + * Copyright (c) 2010, Wei Mingzhi . + * All Rights Reserved. + * + * Based on: Cdrom for Psemu Pro like Emulators + * By: linuzappz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef __CDR_H__ +#define __CDR_H__ + +//#define DEBUG 1 + +#include "config.h" + +#ifdef ENABLE_NLS +#include +#include +#define _(x) gettext(x) +#define N_(x) (x) +#else +#define _(x) (x) +#define N_(x) (x) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "psemu_plugin_defs.h" + +#if defined (__linux__) + +#include +#include +#include + +#ifndef CDROMSETSPINDOWN +#define CDROMSETSPINDOWN 0x531e +#endif + +#define DEV_DEF "/dev/cdrom" + +#else + +struct cdrom_msf { + unsigned char cdmsf_min0; /* start minute */ + unsigned char cdmsf_sec0; /* start second */ + unsigned char cdmsf_frame0; /* start frame */ + unsigned char cdmsf_min1; /* end minute */ + unsigned char cdmsf_sec1; /* end second */ + unsigned char cdmsf_frame1; /* end frame */ +}; + +#define CD_SECS 60 +#define CD_FRAMES 75 +#define CD_MSF_OFFSET 150 +#define CD_FRAMESIZE_SUB 96 + +#if defined (__FreeBSD__) +#define DEV_DEF "/dev/cd0" +#else +#define DEV_DEF "" +#endif + +#if !defined (USE_LIBCDIO) && !defined (_MACOSX) +#define USE_NULL 1 +#endif + +#endif + +extern char CdromDev[256]; +extern long ReadMode; +extern long UseSubQ; +extern long CacheSize; +extern long CdrSpeed; +extern long SpinDown; + +#define NORMAL 0 +#define THREADED 1 +#define READ_MODES 2 + +#ifndef CD_FRAMESIZE_RAW +#define CD_FRAMESIZE_RAW 2352 +#endif + +#define DATA_SIZE (CD_FRAMESIZE_RAW - 12) + +// spindown codes +#define SPINDOWN_VENDOR_SPECIFIC 0x00 +#define SPINDOWN_125MS 0x01 +#define SPINDOWN_250MS 0x02 +#define SPINDOWN_500MS 0x03 +#define SPINDOWN_1S 0x04 +#define SPINDOWN_2S 0x05 +#define SPINDOWN_4S 0x06 +#define SPINDOWN_8S 0x07 +#define SPINDOWN_16S 0x08 +#define SPINDOWN_32S 0x09 +#define SPINDOWN_1MIN 0x0A +#define SPINDOWN_2MIN 0x0B +#define SPINDOWN_4MIN 0x0C +#define SPINDOWN_8MIN 0x0D +#define SPINDOWN_16MIN 0x0E +#define SPINDOWN_32MIN 0x0F + +typedef struct _MMC_READ_CD { + unsigned char Code; // 0xBE + + unsigned char RelativeAddress : 1; + unsigned char : 1; + unsigned char ExpectedSectorType : 3; + unsigned char Lun : 3; + + unsigned char StartingLBA[4]; + unsigned char TransferBlocks[3]; + + unsigned char : 1; + unsigned char ErrorFlags : 2; + unsigned char IncludeEDC : 1; + unsigned char IncludeUserData : 1; + unsigned char HeaderCode : 2; + unsigned char IncludeSyncData : 1; + + unsigned char SubChannelSelection : 3; + unsigned char : 5; + + unsigned char Ctrl; +} MMC_READ_CD; + +#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ +#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ + +struct CdrStat { + unsigned long Type; + unsigned long Status; + unsigned char Time[3]; // current playing time +}; + +struct SubQ { + char res0[12]; + unsigned char ControlAndADR; + unsigned char TrackNumber; + unsigned char IndexNumber; + unsigned char TrackRelativeAddress[3]; + unsigned char Filler; + unsigned char AbsoluteAddress[3]; + unsigned char CRC[2]; + char res1[72]; +}; + +typedef union { + struct cdrom_msf msf; + unsigned char buf[CD_FRAMESIZE_RAW]; +} crdata; + +typedef struct { + unsigned char msf[3]; + crdata cr; + int ret; +} CacheData; + +long ReadNormal(); +long ReadThreaded(); +unsigned char* GetBNormal(); +unsigned char* GetBThreaded(); + +long CDRstop(void); + +void LoadConf(); +void SaveConf(); + +#ifdef DEBUG +#define PRINTF printf +#else +#define PRINTF(...) /* */ +#endif + +unsigned int msf_to_lba(char m, char s, char f); +void lba_to_msf(unsigned int s, unsigned char *msf); +void DecodeRawSubData(unsigned char *subbuffer); +unsigned short calcCrc(unsigned char *d, int len); + +int OpenCdHandle(); +void CloseCdHandle(); +int IsCdHandleOpen(); +long GetTN(unsigned char *buffer); +long GetTD(unsigned char track, unsigned char *buffer); +long GetTE(unsigned char track, unsigned char *m, unsigned char *s, unsigned char *f); +long ReadSector(crdata *cr); +long PlayCDDA(unsigned char *sector); +long StopCDDA(); +long GetStatus(int playing, struct CdrStat *stat); +unsigned char *ReadSub(const unsigned char *time); + +#endif diff --git a/plugins/dfcdrom/cdrcfg-0.1df/main.c b/plugins/dfcdrom/cdrcfg-0.1df/main.c index 454a4e2d..fbbe29d5 100644 --- a/plugins/dfcdrom/cdrcfg-0.1df/main.c +++ b/plugins/dfcdrom/cdrcfg-0.1df/main.c @@ -1,290 +1,290 @@ -/* - * Copyright (c) 2010, Wei Mingzhi . - * All Rights Reserved. - * - * Based on: Cdrom for Psemu Pro like Emulators - * By: linuzappz - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include "../cfg.c" - -#include -#include - -GtkWidget *MainWindow; - -// function to check if the device is a cdrom -static int is_cdrom(const char *device) { - struct stat st; - int fd = -1; - - // check if the file exist - if (stat(device, &st) < 0) return 0; - - // check if is a block or char device - if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) return 0; - - // try to open the device file descriptor - if ((fd = open(device, O_RDONLY | O_NONBLOCK)) < 0) return 0; - -#ifdef __linux__ - // I need a method to check is a device is really a CD-ROM. - // some problems/ideas are: - // - different protocls (ide, scsi, old proprietary...) - // - maybe we can use major number (see linux/major.h) to do some check. - // major number can be retrieved with (st.st_rdev>>8) - // scsi has SCSI_CDROM_MAJOR but does this cover all scsi drives? - // beside IDE major is the same for hard disks and cdroms... - // and DVDs? - // - another idea is to parse /proc, but again IDE, scsi etc have - // different files... I've not found a way to query "which CD drives - // are available?" - // - // Now I use this ioctl which works also if the drive is empty, - // I hope that is implemented for all the drives... here works - // fine: at least doesn't let me to select my HD as CDs ;) - - // try a ioctl to see if it's a CD-ROM device - if (ioctl(fd, CDROM_GET_CAPABILITY, NULL) < 0) { - close(fd); - return 0; - } -#endif - - close(fd); - - // yes, it seems a CD drive! - return 1; -} - -// fill_drives_list: retrieves available cd drives. At the moment it use a quite -// ugly "brute force" method: we check for the most common location for cdrom -// in /dev and chech if they are cdrom devices. -// If your cdrom path is not listed here you'll have to type it in the dialog -// entry yourself (or add it here and recompile). -// Are there any other common entry to add to the list? (especially scsi, I -// deliberately ignored old non standard cdroms... ) -// If you come up with a better method let me know!! -static void fill_drives_list(GtkWidget *widget) { - int i; - GtkListStore *store; - GtkTreeIter iter; - -#if defined (__linux__) - static const char *cdrom_devices[] = { - "/dev/cdrom", - "/dev/cdrom0", - "/dev/cdrom1", - "/dev/cdrom2", - "/dev/cdrom3", - "/dev/cdroms/cdrom0", - "/dev/cdroms/cdrom1", - "/dev/cdroms/cdrom2", - "/dev/cdroms/cdrom3", - "/dev/hda", - "/dev/hdb", - "/dev/hdc", - "/dev/hdd", - "/dev/sda", - "/dev/sdb", - "/dev/sdc", - "/dev/sdd", - "/dev/scd0", - "/dev/scd1", - "/dev/scd2", - "/dev/scd3", - "/dev/optcd", - ""}; -#elif defined (__FreeBSD__) - static const char *cdrom_devices[] = { - "/dev/cd0", - "/dev/cd1", - "/dev/cd2", - "/dev/cd3", - ""}; -#elif defined (__sun) - char cdrom_devices[256][256]; - FILE *fp; - char buf[256], *devname, *nick; - - memset(cdrom_devices, 0, sizeof(cdrom_devices)); - - i = 0; - - fp = popen("eject -l", "r"); - - if (fp != NULL) { - while (!feof(fp) && i < 256) { - fgets(buf, 256, fp); - - devname = strtok(buf, " "); - nick = strtok(NULL, " "); - - if (devname == NULL || nick == NULL) continue; - - if (strstr(nick, "cdrom") != NULL) { - strcpy(cdrom_devices[i++], devname); - } - } - - pclose(fp); - } -#else - static const char *cdrom_devices[] = { "" }; -#endif - - store = gtk_list_store_new(1, G_TYPE_STRING); - - // first we put our current drive - if (CdromDev[0] != '\0') { - gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, 0, CdromDev, -1); - } - - i = 0; - - // scan cdrom_devices for real cdrom and add them to list - while (cdrom_devices[i][0] != '\0') { - // check that is not our current dev (already in list) - if (strcmp(cdrom_devices[i], CdromDev) != 0) { - // check that is a cdrom device - if (is_cdrom(cdrom_devices[i])) { - gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, 0, cdrom_devices[i], -1); - } - } - ++i; - } - - gtk_combo_box_set_model(GTK_COMBO_BOX(widget), GTK_TREE_MODEL(store)); - gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(widget), 0); -} - -static void OnConfigExit(GtkWidget *widget, gpointer user_data) { - GladeXML *xml; - - xml = glade_get_widget_tree(MainWindow); - - widget = glade_xml_get_widget(xml, "cddev_comboboxentry"); - strncpy(CdromDev, gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(widget)))), 255); - CdromDev[255] = '\0'; - - widget = glade_xml_get_widget(xml, "readmode_combobox"); - ReadMode = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); - - widget = glade_xml_get_widget(xml, "subQ_button"); - UseSubQ = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); - - widget = glade_xml_get_widget(xml, "spinCacheSize"); - CacheSize = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); - - widget = glade_xml_get_widget(xml, "spinCdrSpeed"); - CdrSpeed = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); - - widget = glade_xml_get_widget(xml, "comboSpinDown"); - SpinDown = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); - - SaveConf(); - - gtk_widget_destroy(widget); - gtk_exit(0); -} - -long CDRconfigure() { - GladeXML *xml; - GtkWidget *widget; - - LoadConf(); - - xml = glade_xml_new(DATADIR "dfcdrom.glade2", "CfgWnd", NULL); - if (xml == NULL) { - g_warning("We could not load the interface!"); - return -1; - } - - MainWindow = glade_xml_get_widget(xml, "CfgWnd"); - gtk_window_set_title(GTK_WINDOW(MainWindow), _("CDR configuration")); - - widget = glade_xml_get_widget(xml, "CfgWnd"); - g_signal_connect_data(GTK_OBJECT(widget), "delete_event", - G_CALLBACK(OnConfigExit), NULL, NULL, G_CONNECT_AFTER); - - widget = glade_xml_get_widget(xml, "cfg_closebutton"); - g_signal_connect_data(GTK_OBJECT(widget), "clicked", - G_CALLBACK(OnConfigExit), NULL, NULL, G_CONNECT_AFTER); - - widget = glade_xml_get_widget(xml, "cddev_comboboxentry"); - fill_drives_list(widget); - gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(widget))), CdromDev); - - widget = glade_xml_get_widget(xml, "readmode_combobox"); - gtk_combo_box_set_active(GTK_COMBO_BOX(widget), ReadMode); - - widget = glade_xml_get_widget(xml, "subQ_button"); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), UseSubQ); - - widget = glade_xml_get_widget(xml, "spinCacheSize"); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), (float)CacheSize); - - widget = glade_xml_get_widget(xml, "spinCdrSpeed"); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), (float)CdrSpeed); - - widget = glade_xml_get_widget(xml, "comboSpinDown"); - gtk_combo_box_set_active(GTK_COMBO_BOX(widget), SpinDown); - - gtk_widget_show(MainWindow); - gtk_main(); - - return 0; -} - -void CDRabout() { - GtkWidget *widget; - const char *authors[]= {"linuzappz ", - "xobro <_xobro_@tin.it>", - "Wei Mingzhi ", NULL}; - - widget = gtk_about_dialog_new(); - gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(widget), "CD-ROM Device Reader"); - gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(widget), "1.0"); - gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(widget), authors); - gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(widget), "http://pcsxr.codeplex.com/"); - - gtk_dialog_run(GTK_DIALOG(widget)); - gtk_widget_destroy(widget); -} - -int main(int argc, char *argv[]) { -#ifdef ENABLE_NLS - setlocale(LC_ALL, ""); - bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR); - bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); - textdomain(GETTEXT_PACKAGE); -#endif - - gtk_set_locale(); - gtk_init(&argc, &argv); - - if (argc != 2) return 0; - - if (strcmp(argv[1], "configure") == 0) { - CDRconfigure(); - } else { - CDRabout(); - } - - return 0; -} +/* + * Copyright (c) 2010, Wei Mingzhi . + * All Rights Reserved. + * + * Based on: Cdrom for Psemu Pro like Emulators + * By: linuzappz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "../cfg.c" + +#include +#include + +GtkWidget *MainWindow; + +// function to check if the device is a cdrom +int is_cdrom(const char *device) { + struct stat st; + int fd = -1; + + // check if the file exist + if (stat(device, &st) < 0) return 0; + + // check if is a block or char device + if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) return 0; + + // try to open the device file descriptor + if ((fd = open(device, O_RDONLY | O_NONBLOCK)) < 0) return 0; + +#ifdef __linux__ + // I need a method to check is a device is really a CD-ROM. + // some problems/ideas are: + // - different protocls (ide, scsi, old proprietary...) + // - maybe we can use major number (see linux/major.h) to do some check. + // major number can be retrieved with (st.st_rdev>>8) + // scsi has SCSI_CDROM_MAJOR but does this cover all scsi drives? + // beside IDE major is the same for hard disks and cdroms... + // and DVDs? + // - another idea is to parse /proc, but again IDE, scsi etc have + // different files... I've not found a way to query "which CD drives + // are available?" + // + // Now I use this ioctl which works also if the drive is empty, + // I hope that is implemented for all the drives... here works + // fine: at least doesn't let me to select my HD as CDs ;) + + // try a ioctl to see if it's a CD-ROM device + if (ioctl(fd, CDROM_GET_CAPABILITY, NULL) < 0) { + close(fd); + return 0; + } +#endif + + close(fd); + + // yes, it seems a CD drive! + return 1; +} + +// fill_drives_list: retrieves available cd drives. At the moment it use a quite +// ugly "brute force" method: we check for the most common location for cdrom +// in /dev and chech if they are cdrom devices. +// If your cdrom path is not listed here you'll have to type it in the dialog +// entry yourself (or add it here and recompile). +// Are there any other common entry to add to the list? (especially scsi, I +// deliberately ignored old non standard cdroms... ) +// If you come up with a better method let me know!! +void fill_drives_list(GtkWidget *widget) { + int i; + GtkListStore *store; + GtkTreeIter iter; + +#if defined (__linux__) + static const char *cdrom_devices[] = { + "/dev/cdrom", + "/dev/cdrom0", + "/dev/cdrom1", + "/dev/cdrom2", + "/dev/cdrom3", + "/dev/cdroms/cdrom0", + "/dev/cdroms/cdrom1", + "/dev/cdroms/cdrom2", + "/dev/cdroms/cdrom3", + "/dev/hda", + "/dev/hdb", + "/dev/hdc", + "/dev/hdd", + "/dev/sda", + "/dev/sdb", + "/dev/sdc", + "/dev/sdd", + "/dev/scd0", + "/dev/scd1", + "/dev/scd2", + "/dev/scd3", + "/dev/optcd", + ""}; +#elif defined (__FreeBSD__) + static const char *cdrom_devices[] = { + "/dev/cd0", + "/dev/cd1", + "/dev/cd2", + "/dev/cd3", + ""}; +#elif defined (__sun) + char cdrom_devices[256][256]; + FILE *fp; + char buf[256], *devname, *nick; + + memset(cdrom_devices, 0, sizeof(cdrom_devices)); + + i = 0; + + fp = popen("eject -l", "r"); + + if (fp != NULL) { + while (!feof(fp) && i < 256) { + fgets(buf, 256, fp); + + devname = strtok(buf, " "); + nick = strtok(NULL, " "); + + if (devname == NULL || nick == NULL) continue; + + if (strstr(nick, "cdrom") != NULL) { + strcpy(cdrom_devices[i++], devname); + } + } + + pclose(fp); + } +#else + static const char *cdrom_devices[] = { "" }; +#endif + + store = gtk_list_store_new(1, G_TYPE_STRING); + + // first we put our current drive + if (CdromDev[0] != '\0') { + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, CdromDev, -1); + } + + i = 0; + + // scan cdrom_devices for real cdrom and add them to list + while (cdrom_devices[i][0] != '\0') { + // check that is not our current dev (already in list) + if (strcmp(cdrom_devices[i], CdromDev) != 0) { + // check that is a cdrom device + if (is_cdrom(cdrom_devices[i])) { + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, cdrom_devices[i], -1); + } + } + ++i; + } + + gtk_combo_box_set_model(GTK_COMBO_BOX(widget), GTK_TREE_MODEL(store)); + gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(widget), 0); +} + +static void OnConfigExit(GtkWidget *widget, gpointer user_data) { + GladeXML *xml; + + xml = glade_get_widget_tree(MainWindow); + + widget = glade_xml_get_widget(xml, "cddev_comboboxentry"); + strncpy(CdromDev, gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(widget)))), 255); + CdromDev[255] = '\0'; + + widget = glade_xml_get_widget(xml, "readmode_combobox"); + ReadMode = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); + + widget = glade_xml_get_widget(xml, "subQ_button"); + UseSubQ = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + + widget = glade_xml_get_widget(xml, "spinCacheSize"); + CacheSize = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + + widget = glade_xml_get_widget(xml, "spinCdrSpeed"); + CdrSpeed = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); + + widget = glade_xml_get_widget(xml, "comboSpinDown"); + SpinDown = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); + + SaveConf(); + + gtk_widget_destroy(widget); + gtk_exit(0); +} + +long CDRconfigure() { + GladeXML *xml; + GtkWidget *widget; + + LoadConf(); + + xml = glade_xml_new(DATADIR "dfcdrom.glade2", "CfgWnd", NULL); + if (xml == NULL) { + g_warning("We could not load the interface!"); + return -1; + } + + MainWindow = glade_xml_get_widget(xml, "CfgWnd"); + gtk_window_set_title(GTK_WINDOW(MainWindow), _("CDR configuration")); + + widget = glade_xml_get_widget(xml, "CfgWnd"); + g_signal_connect_data(GTK_OBJECT(widget), "delete_event", + G_CALLBACK(OnConfigExit), NULL, NULL, G_CONNECT_AFTER); + + widget = glade_xml_get_widget(xml, "cfg_closebutton"); + g_signal_connect_data(GTK_OBJECT(widget), "clicked", + G_CALLBACK(OnConfigExit), NULL, NULL, G_CONNECT_AFTER); + + widget = glade_xml_get_widget(xml, "cddev_comboboxentry"); + fill_drives_list(widget); + gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(widget))), CdromDev); + + widget = glade_xml_get_widget(xml, "readmode_combobox"); + gtk_combo_box_set_active(GTK_COMBO_BOX(widget), ReadMode); + + widget = glade_xml_get_widget(xml, "subQ_button"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), UseSubQ); + + widget = glade_xml_get_widget(xml, "spinCacheSize"); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), (float)CacheSize); + + widget = glade_xml_get_widget(xml, "spinCdrSpeed"); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), (float)CdrSpeed); + + widget = glade_xml_get_widget(xml, "comboSpinDown"); + gtk_combo_box_set_active(GTK_COMBO_BOX(widget), SpinDown); + + gtk_widget_show(MainWindow); + gtk_main(); + + return 0; +} + +void CDRabout() { + GtkWidget *widget; + const char *authors[]= {"linuzappz ", + "xobro <_xobro_@tin.it>", + "Wei Mingzhi ", NULL}; + + widget = gtk_about_dialog_new(); + gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(widget), "CD-ROM Device Reader"); + gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(widget), "1.0"); + gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(widget), authors); + gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(widget), "http://pcsxr.codeplex.com/"); + + gtk_dialog_run(GTK_DIALOG(widget)); + gtk_widget_destroy(widget); +} + +int main(int argc, char *argv[]) { +#ifdef ENABLE_NLS + setlocale(LC_ALL, ""); + bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR); + bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); + textdomain(GETTEXT_PACKAGE); +#endif + + gtk_set_locale(); + gtk_init(&argc, &argv); + + if (argc != 2) return 0; + + if (strcmp(argv[1], "configure") == 0) { + CDRconfigure(); + } else { + CDRabout(); + } + + return 0; +} diff --git a/plugins/dfcdrom/cfg.c b/plugins/dfcdrom/cfg.c index 6985eda6..1ded04c8 100644 --- a/plugins/dfcdrom/cfg.c +++ b/plugins/dfcdrom/cfg.c @@ -1,101 +1,99 @@ -/* - * Copyright (c) 2010, Wei Mingzhi . - * All Rights Reserved. - * - * Based on: Cdrom for Psemu Pro like Emulators - * By: linuzappz - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include "cdr.h" - -char CdromDev[256]; -long ReadMode; -long UseSubQ; -long CacheSize; -long CdrSpeed; -long SpinDown; - -void LoadConf() { - FILE *f; - -#if defined (__sun) - char buf[256], *devname, *nick; - - CdromDev[0] = '\0'; - f = popen("eject -l", "r"); - - if (f != NULL) { - while (!feof(f)) { - fgets(buf, 256, f); - - devname = strtok(buf, " "); - nick = strtok(NULL, " "); - - if (devname == NULL || nick == NULL) continue; - - if (strstr(nick, "cdrom") != NULL) { - strcpy(CdromDev, devname); - break; - } - } - - pclose(f); - } -#else - strcpy(CdromDev, DEV_DEF); -#endif - - ReadMode = THREADED; - UseSubQ = 0; - CacheSize = 64; - CdrSpeed = 0; - SpinDown = SPINDOWN_VENDOR_SPECIFIC; - - f = fopen("dfcdrom.cfg", "r"); - if (f == NULL) return; - - if(fscanf(f, "CdromDev = %s\n", CdromDev) != 1 || - fscanf(f, "ReadMode = %ld\n", &ReadMode) != 1 || - fscanf(f, "UseSubQ = %ld\n", &UseSubQ) != 1 || - fscanf(f, "CacheSize = %ld\n", &CacheSize) != 1 || - fscanf(f, "CdrSpeed = %ld\n", &CdrSpeed) != 1 || - fscanf(f, "SpinDown = %ld\n", &SpinDown) != 1) { - perror("syntax error in dfcdrom.cfg"); - } - fclose(f); - - if (ReadMode >= READ_MODES) ReadMode = THREADED; - if (CacheSize <= 0) CacheSize = 32; - if (CacheSize > 2048) CacheSize = 2048; - if (SpinDown <= 0) SpinDown = SPINDOWN_VENDOR_SPECIFIC; - if (SpinDown > SPINDOWN_32MIN) SpinDown = SPINDOWN_32MIN; -} - -void SaveConf() { - FILE *f; - - f = fopen("dfcdrom.cfg", "w"); - if (f == NULL) - return; - - fprintf(f, "CdromDev = %s\n", CdromDev); - fprintf(f, "ReadMode = %ld\n", ReadMode); - fprintf(f, "UseSubQ = %ld\n", UseSubQ); - fprintf(f, "CacheSize = %ld\n", CacheSize); - fprintf(f, "CdrSpeed = %ld\n", CdrSpeed); - fprintf(f, "SpinDown = %ld\n", SpinDown); - fclose(f); -} +/* + * Copyright (c) 2010, Wei Mingzhi . + * All Rights Reserved. + * + * Based on: Cdrom for Psemu Pro like Emulators + * By: linuzappz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "cdr.h" + +char CdromDev[256]; +long ReadMode; +long UseSubQ; +long CacheSize; +long CdrSpeed; +long SpinDown; + +void LoadConf() { + FILE *f; + +#if defined (__sun) + char buf[256], *devname, *nick; + + CdromDev[0] = '\0'; + f = popen("eject -l", "r"); + + if (f != NULL) { + while (!feof(f)) { + fgets(buf, 256, f); + + devname = strtok(buf, " "); + nick = strtok(NULL, " "); + + if (devname == NULL || nick == NULL) continue; + + if (strstr(nick, "cdrom") != NULL) { + strcpy(CdromDev, devname); + break; + } + } + + pclose(f); + } +#else + strcpy(CdromDev, DEV_DEF); +#endif + + ReadMode = THREADED; + UseSubQ = 0; + CacheSize = 64; + CdrSpeed = 0; + SpinDown = SPINDOWN_VENDOR_SPECIFIC; + + f = fopen("dfcdrom.cfg", "r"); + if (f == NULL) return; + + fscanf(f, "CdromDev = %s\n", CdromDev); + fscanf(f, "ReadMode = %ld\n", &ReadMode); + fscanf(f, "UseSubQ = %ld\n", &UseSubQ); + fscanf(f, "CacheSize = %ld\n", &CacheSize); + fscanf(f, "CdrSpeed = %ld\n", &CdrSpeed); + fscanf(f, "SpinDown = %ld\n", &SpinDown); + fclose(f); + + if (ReadMode >= READ_MODES) ReadMode = THREADED; + if (CacheSize <= 0) CacheSize = 32; + if (CacheSize > 2048) CacheSize = 2048; + if (SpinDown <= 0) SpinDown = SPINDOWN_VENDOR_SPECIFIC; + if (SpinDown > SPINDOWN_32MIN) SpinDown = SPINDOWN_32MIN; +} + +void SaveConf() { + FILE *f; + + f = fopen("dfcdrom.cfg", "w"); + if (f == NULL) + return; + + fprintf(f, "CdromDev = %s\n", CdromDev); + fprintf(f, "ReadMode = %ld\n", ReadMode); + fprintf(f, "UseSubQ = %ld\n", UseSubQ); + fprintf(f, "CacheSize = %ld\n", CacheSize); + fprintf(f, "CdrSpeed = %ld\n", CdrSpeed); + fprintf(f, "SpinDown = %ld\n", SpinDown); + fclose(f); +} -- cgit v1.2.3