Mercurial > repos > blastem
comparison cue.c @ 2076:3f29e2726522
Added basic support for ISO images for games that only have a data track
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 31 Jan 2022 22:07:18 -0800 |
parents | c5323c02dde4 |
children | 5a2b759f6b2d |
comparison
equal
deleted
inserted
replaced
2075:983f57d08eff | 2076:3f29e2726522 |
---|---|
39 } | 39 } |
40 } | 40 } |
41 seconds += minutes * 60; | 41 seconds += minutes * 60; |
42 return seconds * 75 + frames; | 42 return seconds * 75 + frames; |
43 | 43 |
44 } | |
45 | |
46 static void bin_seek(system_media *media, uint32_t sector) | |
47 { | |
48 media->cur_sector = sector; | |
49 uint32_t lba = sector; | |
50 for (uint32_t i = 0; i < media->num_tracks; i++) | |
51 { | |
52 if (lba < media->tracks[i].fake_pregap) { | |
53 media->in_fake_pregap = 1; | |
54 break; | |
55 } | |
56 lba -= media->tracks[i].fake_pregap; | |
57 if (lba < media->tracks[i].start_lba) { | |
58 media->in_fake_pregap = 1; | |
59 break; | |
60 } | |
61 if (lba < media->tracks[i].end_lba) { | |
62 media->in_fake_pregap = 0; | |
63 break; | |
64 } | |
65 } | |
66 if (!media->in_fake_pregap) { | |
67 fseek(media->f, lba * 2352, SEEK_SET); | |
68 } | |
69 } | |
70 | |
71 static uint8_t fake_read(uint32_t sector, uint32_t offset) | |
72 { | |
73 if (!offset || (offset >= 16)) { | |
74 return 0; | |
75 //TODO: error detection and correction bytes | |
76 } else if (offset < 12) { | |
77 return 0xFF; | |
78 } else if (offset == 12) { | |
79 uint32_t minute = (sector / 75) / 60; | |
80 return (minute % 10) | ((minute / 10 ) << 4); | |
81 } else if (offset == 13) { | |
82 uint32_t seconds = (sector / 75) % 60; | |
83 return (seconds % 10) | ((seconds / 10 ) << 4); | |
84 } else if (offset == 14) { | |
85 uint32_t frames = sector % 75; | |
86 return (frames % 10) | ((frames / 10 ) << 4); | |
87 } else { | |
88 return 1; | |
89 } | |
90 } | |
91 | |
92 static uint8_t bin_read(system_media *media, uint32_t offset) | |
93 { | |
94 if (media->in_fake_pregap) { | |
95 return fake_read(media->cur_sector, offset); | |
96 } else { | |
97 return fgetc(media->f); | |
98 } | |
99 } | |
100 | |
101 static void iso_seek(system_media *media, uint32_t sector) | |
102 { | |
103 media->cur_sector = sector; | |
104 if (sector < (2 * 75)) { | |
105 media->in_fake_pregap = 1; | |
106 } else { | |
107 media->in_fake_pregap = 0; | |
108 fseek(media->f, (sector - 2 * 75) * 2048, SEEK_SET); | |
109 } | |
110 } | |
111 | |
112 static uint8_t iso_read(system_media *media, uint32_t offset) | |
113 { | |
114 if (media->in_fake_pregap || offset < 16 || offset > (2048 + 16)) { | |
115 return fake_read(media->cur_sector, offset); | |
116 } else { | |
117 return fgetc(media->f); | |
118 } | |
44 } | 119 } |
45 | 120 |
46 uint8_t parse_cue(system_media *media) | 121 uint8_t parse_cue(system_media *media) |
47 { | 122 { |
48 char *line = media->buffer; | 123 char *line = media->buffer; |
151 } | 226 } |
152 } | 227 } |
153 | 228 |
154 fseek(media->f, 16, SEEK_SET); | 229 fseek(media->f, 16, SEEK_SET); |
155 media->size = fread(media->buffer, 1, 2048, media->f); | 230 media->size = fread(media->buffer, 1, 2048, media->f); |
231 media->seek = bin_seek; | |
232 media->read = bin_read; | |
156 } | 233 } |
157 uint8_t valid = tracks > 0 && media->f != NULL; | 234 uint8_t valid = tracks > 0 && media->f != NULL; |
158 media->type = valid ? MEDIA_CDROM : MEDIA_CART; | 235 media->type = valid ? MEDIA_CDROM : MEDIA_CART; |
159 return valid; | 236 return valid; |
160 } | 237 } |
238 | |
239 uint32_t make_iso_media(system_media *media, const char *filename) | |
240 { | |
241 media->f = fopen(filename, "rb"); | |
242 if (!media->f) { | |
243 return 0; | |
244 } | |
245 media->buffer = calloc(2048, 1); | |
246 media->size = fread(media->buffer, 1, 2048, media->f); | |
247 media->num_tracks = 2; | |
248 media->tracks = calloc(sizeof(track_info), 2); | |
249 media->tracks[0] = (track_info){ | |
250 .fake_pregap = 2 * 75, | |
251 .start_lba = 0, | |
252 .end_lba = file_size(media->f), | |
253 .type = TRACK_DATA | |
254 }; | |
255 media->tracks[1] = (track_info){ | |
256 .fake_pregap = 2 * 75, | |
257 .start_lba = media->tracks[0].end_lba, | |
258 .end_lba = media->tracks[0].end_lba + 2 * 75, | |
259 .type = TRACK_DATA | |
260 }; | |
261 media->type = MEDIA_CDROM; | |
262 media->seek = iso_seek; | |
263 media->read = iso_read; | |
264 return media->size; | |
265 } |