46f0d39126837b705697385f555b99b7ae972534
[pcsx_rearmed.git] / frontend / libretro-cdrom.c
1 #include "libretro-cdrom.h"
2 #include "../deps/libretro-common/cdrom/cdrom.c"
3 #if defined(__linux__) && !defined(ANDROID)
4 //#include <linux/cdrom.h>
5 #endif
6
7 #include "../libpcsxcore/psxcommon.h"
8 #include "../libpcsxcore/cdrom.h"
9
10 //#include "vfs/vfs_implementation.h"
11 #include "vfs/vfs_implementation_cdrom.h"
12
13 static int cdrom_send_command_dummy(const libretro_vfs_implementation_file *stream,
14       CDROM_CMD_Direction dir, void *buf, size_t len, unsigned char *cmd, size_t cmd_len,
15       unsigned char *sense, size_t sense_len)
16 {
17    return 1;
18 }
19
20 static int cdrom_send_command_once(const libretro_vfs_implementation_file *stream,
21       CDROM_CMD_Direction dir, void *buf, size_t len, unsigned char *cmd, size_t cmd_len)
22 {
23    unsigned char sense[CDROM_MAX_SENSE_BYTES] = {0};
24    int ret =
25 #if defined(__linux__) && !defined(ANDROID)
26       cdrom_send_command_linux
27 #elif defined(_WIN32) && !defined(_XBOX)
28       cdrom_send_command_win32
29 #else
30       cdrom_send_command_dummy
31 #endif
32          (stream, dir, buf, len, cmd, cmd_len, sense, sizeof(sense));
33 #ifdef CDROM_DEBUG
34    if (ret && sense[2])
35       cdrom_print_sense_data(sense, sizeof(sense));
36 #endif
37    (void)cdrom_send_command_dummy;
38    return ret;
39 }
40
41 // "extensions" to libretro-common
42 int cdrom_set_read_speed_x(libretro_vfs_implementation_file *stream, unsigned speed)
43 {
44    // SET CD-ROM SPEED, DA is newer?
45    unsigned char cmd1[] = {0xDA, 0, speed - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
46    unsigned char cmd2[] = {0xBB, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
47    int ret;
48    ret = cdrom_send_command_once(stream, DIRECTION_NONE, NULL, 0, cmd1, sizeof(cmd1));
49    if (ret) {
50 #if defined(__linux__) && !defined(ANDROID)
51       // doesn't work, too late?
52       //ret = ioctl(fileno(stream->fp), CDROM_SELECT_SPEED, &speed);
53 #endif
54    }
55    if (ret) {
56       speed = speed * 2352 * 75 / 1024;
57       cmd2[2] = speed >> 8;
58       cmd2[3] = speed;
59       ret = cdrom_send_command_once(stream, DIRECTION_NONE, NULL, 0, cmd2, sizeof(cmd2));
60    }
61    return ret;
62 }
63
64 int rcdrom_readSector(void *stream, unsigned int lba, void *b)
65 {
66    unsigned char cmd[] = {0xBE, 0, 0, 0, 0, 0, 0, 0, 1, 0xF8, 0, 0};
67    cmd[2] = lba >> 24;
68    cmd[3] = lba >> 16;
69    cmd[4] = lba >> 8;
70    cmd[5] = lba;
71    return cdrom_send_command_once(stream, DIRECTION_IN, b, 2352, cmd, sizeof(cmd));
72 }
73
74 void *rcdrom_open(const char *name, u32 *total_lba, u32 *have_subchannel)
75 {
76    void *g_cd_handle = retro_vfs_file_open_impl(name, RETRO_VFS_FILE_ACCESS_READ,
77         RETRO_VFS_FILE_ACCESS_HINT_NONE);
78    if (!g_cd_handle) {
79       SysPrintf("retro_vfs_file_open failed for '%s'\n", name);
80       return NULL;
81    }
82    else {
83       int ret = cdrom_set_read_speed_x(g_cd_handle, 4);
84       if (ret) SysPrintf("CD speed set failed\n");
85       const cdrom_toc_t *toc = retro_vfs_file_get_cdrom_toc();
86       const cdrom_track_t *last = &toc->track[toc->num_tracks - 1];
87       unsigned int lba = MSF2SECT(last->min, last->sec, last->frame);
88       *total_lba = lba + last->track_size;
89       *have_subchannel = 0;
90       //cdrom_get_current_config_random_readable(acdrom.h);
91       //cdrom_get_current_config_multiread(acdrom.h);
92       //cdrom_get_current_config_cdread(acdrom.h);
93       //cdrom_get_current_config_profiles(acdrom.h);
94       return g_cd_handle;
95    }
96 }
97
98 void rcdrom_close(void *stream)
99 {
100    retro_vfs_file_close_impl(stream);
101 }
102
103 int rcdrom_getTN(void *stream, u8 *tn)
104 {
105    const cdrom_toc_t *toc = retro_vfs_file_get_cdrom_toc();
106    if (toc) {
107      tn[0] = 1;
108      tn[1] = toc->num_tracks;
109      return 0;
110    }
111    return -1;
112 }
113
114 int rcdrom_getTD(void *stream, u32 total_lba, u8 track, u8 *rt)
115 {
116    const cdrom_toc_t *toc = retro_vfs_file_get_cdrom_toc();
117    rt[0] = 0, rt[1] = 2, rt[2] = 0;
118    if (track == 0) {
119       lba2msf(total_lba + 150, &rt[0], &rt[1], &rt[2]);
120    }
121    else if (track <= toc->num_tracks) {
122       int i = track - 1;
123       rt[0] = toc->track[i].min;
124       rt[1] = toc->track[i].sec;
125       rt[2] = toc->track[i].frame;
126    }
127    return 0;
128 }
129
130 int rcdrom_getStatus(void *stream, struct CdrStat *stat)
131 {
132    const cdrom_toc_t *toc = retro_vfs_file_get_cdrom_toc();
133    stat->Type = toc->track[0].audio ? 2 : 1;
134    return 0;
135 }
136
137 int rcdrom_isMediaInserted(void *stream)
138 {
139    return cdrom_is_media_inserted(stream);
140 }
141
142 int rcdrom_readSub(void *stream, unsigned int lba, void *b)
143 {
144    return -1;
145 }
146
147 // vim:sw=3:ts=3:expandtab