libsdl-org / sdl12-compat

An SDL-1.2 compatibility layer that uses SDL 2.0 behind the scenes.
Other
196 stars 40 forks source link

Track-based CD-ROM access non-functional #344

Open jengelh opened 2 days ago

jengelh commented 2 days ago

Version: sdl12_compat-1.2.68, openSUSE Tumbleweed 20241129 amd64, tcd 2.2.0

Observed

Starting tcd with sdl12-compat-1.2.68 leads to program termination:

$ strace -e openat,ioctl tcd 
openat(AT_FDCWD, "/lib64/libSDL-1.2.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib64/libncurses.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib64/libtinfo.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
…the usual libc fluff…
INFO: This app is looking for CD-ROM drives, but no path was specified
INFO: Set the SDL12COMPAT_FAKE_CDROM_PATH environment variable to a directory
INFO: of MP3 files named trackXX.mp3 where XX is a track number in two digits
INFO: from 01 to 99
No CDROM devices available
+++ exited with 1 +++

Expected to see instead

With SDL-1.2.15, tcd works fine:

$ strace -e open,ioctl tcd /dev/sr0
openat(AT_FDCWD, "/dev/cdrom", O_RDONLY|O_NONBLOCK) = 3
ioctl(3, CDROMSUBCHNL, 0x7ffec5632210)  = 0
openat(AT_FDCWD, "/etc/mtab", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/dev/sr0", O_RDONLY|O_NONBLOCK) = 4
ioctl(4, CDROMSUBCHNL, 0x7ffec5631960)  = 0
openat(AT_FDCWD, "/etc/fstab", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/dev/cdrom", O_RDONLY|O_NONBLOCK) = 3
ioctl(3, CDROMSUBCHNL, 0x7ffec56323d0)  = 0
…

tcd

icculus commented 1 day ago

So, okay, yes, this doesn't support physical discs, making a CD player app significantly less useful, but this program does work with a directory of MP3s[^1], like the INFO lines say.

The reasons we dropped physical drive support:

  1. Lots of computers don't even have a CD/DVD drive anymore.
  2. On the ones that do (notably, all the Macs sold in the last several years of Apple offering an internal optical disc drive), many weren't hooked up to the audio hardware, so even if SDL could command the drive to play an audio track, the disc would spin but no audio would play. Obviously something like a USB drive will never work with this unless one can plug speakers directly into it.
  3. Some of this could be mitigated by reading the raw data from an audio CD and playing it through a sound card directly, but SDL 1.2 never offered this outside of Mac OS X; most platforms just sent a "play" command to the drive in some way.
  4. On a source code level: every platform did their own thing for CD audio control: not just Windows vs Linux vs Mac, but also Linux vs FreeBSD vs OpenBSD vs AIX, etc. the source code to SDL-1.2's cdrom subsystem, with all these variations, is larger than all of sdl12-compat as a whole. Also: it's LGPL'd, so we'd have to rewrite it from scratch it instead of incorporate it, since we can't comply with the license in sdl12-compat.

The thinking is that faking audio discs with a directory of MP3s fixes up a generation of games that have CD audio tracks--like Quake 1, etc--for modern systems that might be able to play the game but can't even insert a physical disc.

Obviously all of this does not help tcd at all though. If we were to deal better with this, my thinking would be:

  1. Many of those platforms (Mac OS Classic, Dreamcast, etc) can't run SDL2 at all, let alone sdl12-compat, so we don't have to reimplement everything. In fact, I'd be surprised if there were any generic CD Audio apps (not games) using SDL 1.2 outside of Linux, so maybe implementing exactly one platform is the correct thing to do here.
  2. For platforms we might implement, we definitely still want the MP3 support for all the reasons mentioned; it would just be one more reported drive over any physical drives.

Right now sdl12-compat's entire CD subsystem runs on the expectation that there's either zero drives, or one fake drive, and all of that would need to get more generalized if we're going to drop platform-specific code in here to work with actual physical hardware.

I'm putting this in the next milestone, but I'm extremely likely to bump it back out, as this is low-priority for me. If someone else wants to take a run at it before I get around to it, I'm happy to help, though.

[^1]: I had to fix a buffer overflow in cddb.c's cddb_filename where it ended up with a massively large value for discid, presumably because somewhere it's trying to read real data from a Linux CD-ROM drive device node, outside of SDL, that doesn't exist, and long went from 32 to 64 bits since tcd was written.

jengelh commented 1 day ago

Lots of computers don't even have a CD/DVD drive anymore.

Rest assured we emulate it already ;-)

# readcd dev=/dev/disk/by-id/usb-TSSTcorp_CDDVDW_SE-208DB_R90V6GAD1006WH-0:0 f=fury3.readcd -clone
# modprobe vhba
# cdemu-daemon &
# cdemu load 0 fury3.readcd.toc
# cdrecord -dev=/dev/disk/by-id/scsi-1CDEmu_CD-ROM_000 -toc
first: 1 last 6
track:   1 lba:         0 (        0) 00:02:00 adr: 1 control: 4 mode: -1
track:   2 lba:    100302 (   401208) 22:19:27 adr: 1 control: 0 mode: -1
track:   3 lba:    124178 (   496712) 27:37:53 adr: 1 control: 0 mode: -1
track:   4 lba:    137278 (   549112) 30:32:28 adr: 1 control: 0 mode: -1
track:   5 lba:    154824 (   619296) 34:26:24 adr: 1 control: 0 mode: -1
track:   6 lba:    179617 (   718468) 39:56:67 adr: 1 control: 0 mode: -1
track:lout lba:    191631 (   766524) 42:37:06 adr: 1 control: 0 mode: -1
sulix commented 7 hours ago

FWIW, I have a super-hacky half-finished proof-of-concept to implement CD-audio using libcdio_paranoia — this does the digital audio extraction (so works with any modern CD/DVD/Blu-Ray drive), and then mixes it in the same way the mp3 implementation works.

I think, if I clean it up and update it to (a) not hang the audio thread while the drive is spinning up, and (b) make it dlopen() the cdio/cdio_paranoia libraries, then this could be a pretty good solution. (If we were building on top of SDL3's new audio API, this'd actually be really quite easy. As-is it'd be uglier, but not too bad if done carefully.)

Feel free to assign this to me if that sounds like a good plan, and I'll try to get something done over the holidays.

slouken commented 5 hours ago

FWIW, I have a super-hacky half-finished proof-of-concept to implement CD-audio using libcdio_paranoia

Sure!

jengelh commented 16 minutes ago

cdemu has audio output on its own, so I'd already be happy if SDL just sent the necessary ioctls :-)