Add support for BIN/CUE images. Patch from bit, BIN/CUE handling from DOSBox.
This commit is contained in:
parent
828224d148
commit
a2f44b8ea7
21 changed files with 1363 additions and 423 deletions
|
|
@ -16,7 +16,7 @@ pcem_LDADD = $(allegro_LIBS) -lopenal
|
|||
|
||||
pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c allegro-gui.c \
|
||||
allegro-gui-config-sel.c allegro-gui-configure.c allegro-gui-deviceconfig.c allegro-gui-hdconf.c allegro-joystick.c allegro-keyboard.c allegro-main.c \
|
||||
allegro-midi.c allegro-mouse.c allegro-video.c amstrad.c cdrom-ioctl-linux.c cdrom-iso.c cdrom-null.c \
|
||||
allegro-midi.c allegro-mouse.c allegro-video.c amstrad.c cdrom-ioctl-linux.c cdrom-image.c cdrom-null.c \
|
||||
codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \
|
||||
dac.c dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \
|
||||
hdd.c hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \
|
||||
|
|
@ -32,7 +32,7 @@ vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti06
|
|||
vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c \
|
||||
vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \
|
||||
vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c vid_voodoo.c video.c wd76c10.c vid_wy700.c \
|
||||
x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc dosbox/dbopl.cpp \
|
||||
x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \
|
||||
dosbox/vid_cga_comp.c resid-fp/convolve.cc resid-fp/convolve-sse.cc resid-fp/envelope.cc \
|
||||
resid-fp/extfilt.cc resid-fp/filter.cc resid-fp/pot.cc resid-fp/sid.cc \
|
||||
resid-fp/voice.cc resid-fp/wave6581_PS_.cc resid-fp/wave6581_PST.cc \
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32
|
|||
LDFLAGS = -m32
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \
|
||||
allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \
|
||||
allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-iso.o cdrom-null.o \
|
||||
allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \
|
||||
codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \
|
||||
dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \
|
||||
hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \
|
||||
|
|
@ -22,7 +22,7 @@ vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_
|
|||
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
|
||||
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_wy700.o vid_voodoo.o video.o wd76c10.o \
|
||||
x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o
|
||||
DBOBJ = dbopl.o vid_cga_comp.o
|
||||
DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o
|
||||
SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ CC = gcc
|
|||
CFLAGS = -O3 -fomit-frame-pointer -msse2 -m64
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \
|
||||
allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \
|
||||
allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-iso.o cdrom-null.o \
|
||||
allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \
|
||||
codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \
|
||||
dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \
|
||||
hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \
|
||||
|
|
@ -21,7 +21,7 @@ vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_
|
|||
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \
|
||||
vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \
|
||||
x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o
|
||||
DBOBJ = dbopl.o vid_cga_comp.o
|
||||
DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o
|
||||
SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ CPP = g++.exe
|
|||
CC = gcc.exe
|
||||
WINDRES = windres.exe
|
||||
CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.o \
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \
|
||||
codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \
|
||||
dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \
|
||||
i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \
|
||||
|
|
@ -21,7 +21,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad
|
|||
vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \
|
||||
win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \
|
||||
win-status.o win-video.o x86seg.o x87.o xtide.o pc.res
|
||||
DBOBJ = dbopl.o vid_cga_comp.o
|
||||
DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o
|
||||
SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ CPP = g++.exe
|
|||
CC = gcc.exe
|
||||
WINDRES = windres.exe
|
||||
CFLAGS = -O3 -fomit-frame-pointer -msse2 -Wall -Werror -fno-strict-aliasing
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.o \
|
||||
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \
|
||||
codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \
|
||||
dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \
|
||||
i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \
|
||||
|
|
@ -21,7 +21,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad
|
|||
vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \
|
||||
win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \
|
||||
win-status.o win-video.o x86seg.o x87.o xtide.o pc.res
|
||||
DBOBJ = dbopl.o vid_cga_comp.o
|
||||
DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o
|
||||
SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include "disc.h"
|
||||
#include "ide.h"
|
||||
#include "cdrom-ioctl.h"
|
||||
#include "cdrom-iso.h"
|
||||
#include "cdrom-image.h"
|
||||
#include "cdrom-null.h"
|
||||
|
||||
void warning(const char *format, ...)
|
||||
|
|
@ -128,7 +128,7 @@ static void cdrom_update()
|
|||
case -1:
|
||||
cdrom_menu[1].flags = D_SELECTED;
|
||||
break;
|
||||
case CDROM_ISO:
|
||||
case CDROM_IMAGE:
|
||||
cdrom_menu[3].flags = D_SELECTED;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -200,14 +200,14 @@ static int cdrom_dev()
|
|||
return D_O_K;
|
||||
}
|
||||
|
||||
static int cdrom_iso()
|
||||
static int cdrom_image()
|
||||
{
|
||||
char fn[260];
|
||||
int ret;
|
||||
int xsize = SCREEN_W - 32, ysize = SCREEN_H - 64;
|
||||
|
||||
strcpy(fn, iso_path);
|
||||
ret = file_select_ex("Please choose an ISO image", fn, "ISO", 260, xsize, ysize);
|
||||
strcpy(fn, image_path);
|
||||
ret = file_select_ex("Please choose an image image", fn, "ISO;CUE", 260, xsize, ysize);
|
||||
if (ret)
|
||||
{
|
||||
if (!cdrom_enabled)
|
||||
|
|
@ -220,8 +220,8 @@ static int cdrom_iso()
|
|||
atapi->exit();
|
||||
}
|
||||
|
||||
cdrom_drive = CDROM_ISO;
|
||||
iso_open(fn);
|
||||
cdrom_drive = CDROM_IMAGE;
|
||||
image_open(fn);
|
||||
if (!cdrom_enabled)
|
||||
{
|
||||
cdrom_enabled = 1;
|
||||
|
|
@ -238,7 +238,7 @@ static MENU cdrom_menu[] =
|
|||
{"&Disabled", cdrom_disabled, NULL, 0, NULL},
|
||||
{"&Empty", cdrom_empty, NULL, 0, NULL},
|
||||
{"/dev/cdrom", cdrom_dev, NULL, 0, NULL},
|
||||
{"&ISO image...", cdrom_iso, NULL, 0, NULL},
|
||||
{"&Image...", cdrom_image, NULL, 0, NULL},
|
||||
{NULL,NULL,NULL,0,NULL}
|
||||
};
|
||||
|
||||
|
|
|
|||
551
src/cdrom-image.cc
Normal file
551
src/cdrom-image.cc
Normal file
|
|
@ -0,0 +1,551 @@
|
|||
#include <stdlib.h>
|
||||
#include "cdrom-image.h"
|
||||
#include "dosbox/cdrom.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ibm.h"
|
||||
#include "ide.h"
|
||||
|
||||
int cdrom_drive;
|
||||
int old_cdrom_drive;
|
||||
}
|
||||
|
||||
char image_path[1024];
|
||||
static int image_changed = 0;
|
||||
|
||||
extern ATAPI image_atapi;
|
||||
|
||||
CDROM_Interface_Image *cdrom = NULL;
|
||||
|
||||
#define MSFtoLBA(m,s,f) (((((m*60)+s)*75)+f))
|
||||
|
||||
static uint32_t cdrom_capacity = 0;
|
||||
|
||||
enum
|
||||
{
|
||||
CD_STOPPED = 0,
|
||||
CD_PLAYING,
|
||||
CD_PAUSED
|
||||
};
|
||||
|
||||
static int image_cd_state = CD_STOPPED;
|
||||
static uint32_t image_cd_pos = 0, image_cd_end = 0;
|
||||
|
||||
#define BUF_SIZE 32768
|
||||
static int16_t cd_buffer[BUF_SIZE];
|
||||
static int cd_buflen = 0;
|
||||
|
||||
void image_audio_callback(int16_t *output, int len)
|
||||
{
|
||||
if (image_cd_state != CD_PLAYING)
|
||||
return;
|
||||
while (cd_buflen < len)
|
||||
{
|
||||
if (image_cd_pos < image_cd_end)
|
||||
{
|
||||
// pclog("Read to %i\n", cd_buflen);
|
||||
if (!cdrom->ReadSector((unsigned char *)&cd_buffer[cd_buflen], true, image_cd_pos - 150))
|
||||
{
|
||||
// pclog("DeviceIoControl returned false\n");
|
||||
memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2);
|
||||
image_cd_state = CD_STOPPED;
|
||||
cd_buflen = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
// pclog("DeviceIoControl returned true\n");
|
||||
image_cd_pos++;
|
||||
cd_buflen += (RAW_SECTOR_SIZE / 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2);
|
||||
image_cd_state = CD_STOPPED;
|
||||
cd_buflen = len;
|
||||
}
|
||||
}
|
||||
memcpy(output, cd_buffer, len * 2);
|
||||
memmove(cd_buffer, &cd_buffer[len], (BUF_SIZE - len) * 2);
|
||||
cd_buflen -= len;
|
||||
}
|
||||
|
||||
void image_audio_stop()
|
||||
{
|
||||
image_cd_state = CD_STOPPED;
|
||||
}
|
||||
|
||||
static int image_is_track_audio(uint32_t pos, int ismsf)
|
||||
{
|
||||
if (!cdrom) return 0;
|
||||
if (ismsf)
|
||||
{
|
||||
int m = (pos >> 16) & 0xff;
|
||||
int s = (pos >> 8) & 0xff;
|
||||
int f = pos & 0xff;
|
||||
pos = MSF_TO_FRAMES(m, s, f);
|
||||
}
|
||||
|
||||
unsigned char attr;
|
||||
TMSF tmsf;
|
||||
int number;
|
||||
cdrom->GetAudioTrackInfo(cdrom->GetTrack(pos), number, tmsf, attr);
|
||||
|
||||
return attr == AUDIO_TRACK;
|
||||
}
|
||||
|
||||
static void image_playaudio(uint32_t pos, uint32_t len, int ismsf)
|
||||
{
|
||||
if (!cdrom) return;
|
||||
int number;
|
||||
unsigned char attr;
|
||||
TMSF tmsf;
|
||||
cdrom->GetAudioTrackInfo(cdrom->GetTrack(pos), number, tmsf, attr);
|
||||
if (attr == DATA_TRACK)
|
||||
{
|
||||
pclog("Can't play data track\n");
|
||||
image_cd_pos = 0;
|
||||
image_cd_state = CD_STOPPED;
|
||||
return;
|
||||
}
|
||||
pclog("Play audio - %08X %08X %i\n", pos, len, ismsf);
|
||||
if (ismsf)
|
||||
{
|
||||
int m, s, f;
|
||||
m = (pos >> 16) & 0xff;
|
||||
s = (pos >> 8) & 0xff;
|
||||
f = pos & 0xff;
|
||||
pos = MSFtoLBA(m, s, f);
|
||||
|
||||
m = (len >> 16) & 0xff;
|
||||
s = (len >> 8) & 0xff;
|
||||
f = len & 0xff;
|
||||
len = MSFtoLBA(m, s, f);
|
||||
|
||||
pclog("MSF - pos = %08X len = %08X\n", pos, len);
|
||||
}
|
||||
else
|
||||
len += pos;
|
||||
image_cd_pos = pos;// + 150;
|
||||
image_cd_end = len;// + 150;
|
||||
image_cd_state = CD_PLAYING;
|
||||
if (image_cd_pos < 150)
|
||||
image_cd_pos = 150;
|
||||
cd_buflen = 0;
|
||||
pclog("Audio start %08X %08X %i %i %i\n", image_cd_pos, image_cd_end, image_cd_state, cd_buflen, len);
|
||||
}
|
||||
|
||||
static void image_pause(void)
|
||||
{
|
||||
if (!cdrom) return;
|
||||
if (image_cd_state == CD_PLAYING)
|
||||
image_cd_state = CD_PAUSED;
|
||||
}
|
||||
|
||||
static void image_resume(void)
|
||||
{
|
||||
if (!cdrom) return;
|
||||
if (image_cd_state == CD_PAUSED)
|
||||
image_cd_state = CD_PLAYING;
|
||||
}
|
||||
|
||||
static void image_stop(void)
|
||||
{
|
||||
if (!cdrom) return;
|
||||
image_cd_state = CD_STOPPED;
|
||||
}
|
||||
|
||||
static void image_seek(uint32_t pos)
|
||||
{
|
||||
if (!cdrom) return;
|
||||
image_cd_pos = pos;
|
||||
image_cd_state = CD_STOPPED;
|
||||
}
|
||||
|
||||
static int image_ready(void)
|
||||
{
|
||||
if (!cdrom)
|
||||
return 0;
|
||||
|
||||
if (strlen(image_path) == 0)
|
||||
return 0;
|
||||
|
||||
if (image_changed)
|
||||
image_changed = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int image_get_last_block(unsigned char starttrack, int msf, int maxlen, int single)
|
||||
{
|
||||
int c;
|
||||
uint32_t lb=0;
|
||||
|
||||
if (!cdrom) return 0;
|
||||
|
||||
int first_track;
|
||||
int last_track;
|
||||
int number;
|
||||
unsigned char attr;
|
||||
TMSF tmsf;
|
||||
cdrom->GetAudioTracks(first_track, last_track, tmsf);
|
||||
|
||||
for (c = 0; c <= last_track; c++)
|
||||
{
|
||||
uint32_t address;
|
||||
cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr);
|
||||
address = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150;
|
||||
if (address > lb)
|
||||
lb = address;
|
||||
}
|
||||
return lb;
|
||||
}
|
||||
|
||||
static int image_medium_changed(void)
|
||||
{
|
||||
if (!cdrom)
|
||||
return 0;
|
||||
|
||||
if (strlen(image_path) == 0)
|
||||
return 0;
|
||||
|
||||
if (old_cdrom_drive != cdrom_drive)
|
||||
{
|
||||
old_cdrom_drive = cdrom_drive;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (image_changed)
|
||||
{
|
||||
image_changed = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t image_getcurrentsubchannel(uint8_t *b, int msf)
|
||||
{
|
||||
if (!cdrom) return 0;
|
||||
uint8_t ret;
|
||||
int pos=0;
|
||||
|
||||
uint32_t cdpos = image_cd_pos;
|
||||
if (cdpos >= 150) cdpos -= 150;
|
||||
TMSF relPos, absPos;
|
||||
unsigned char attr, track, index;
|
||||
cdrom->GetAudioSub(cdpos, attr, track, index, relPos, absPos);
|
||||
|
||||
if (image_cd_state == CD_PLAYING)
|
||||
ret = 0x11;
|
||||
else if (image_cd_state == CD_PAUSED)
|
||||
ret = 0x12;
|
||||
else
|
||||
ret = 0x13;
|
||||
|
||||
b[pos++] = attr;
|
||||
b[pos++] = track;
|
||||
b[pos++] = index;
|
||||
|
||||
if (msf)
|
||||
{
|
||||
uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr);
|
||||
b[pos + 3] = (uint8_t)(dat % 75); dat /= 75;
|
||||
b[pos + 2] = (uint8_t)(dat % 60); dat /= 60;
|
||||
b[pos + 1] = (uint8_t)dat;
|
||||
b[pos] = 0;
|
||||
pos += 4;
|
||||
dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr);
|
||||
b[pos + 3] = (uint8_t)(dat % 75); dat /= 75;
|
||||
b[pos + 2] = (uint8_t)(dat % 60); dat /= 60;
|
||||
b[pos + 1] = (uint8_t)dat;
|
||||
b[pos] = 0;
|
||||
pos += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr);
|
||||
b[pos++] = (dat >> 24) & 0xff;
|
||||
b[pos++] = (dat >> 16) & 0xff;
|
||||
b[pos++] = (dat >> 8) & 0xff;
|
||||
b[pos++] = dat & 0xff;
|
||||
dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr);
|
||||
b[pos++] = (dat >> 24) & 0xff;
|
||||
b[pos++] = (dat >> 16) & 0xff;
|
||||
b[pos++] = (dat >> 8) & 0xff;
|
||||
b[pos++] = dat & 0xff;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void image_eject(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void image_load(void)
|
||||
{
|
||||
}
|
||||
|
||||
static int image_readsector(uint8_t *b, int sector)
|
||||
{
|
||||
if (!cdrom) return -1;
|
||||
return !cdrom->ReadSector(b, false, sector);
|
||||
}
|
||||
|
||||
static void image_readsector_raw(uint8_t *b, int sector)
|
||||
{
|
||||
if (!cdrom) return;
|
||||
cdrom->ReadSector(b, true, sector);
|
||||
}
|
||||
|
||||
static int image_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single)
|
||||
{
|
||||
if (!cdrom) return 0;
|
||||
int len=4;
|
||||
int c,d;
|
||||
uint32_t temp;
|
||||
|
||||
int first_track;
|
||||
int last_track;
|
||||
int number;
|
||||
unsigned char attr;
|
||||
TMSF tmsf;
|
||||
cdrom->GetAudioTracks(first_track, last_track, tmsf);
|
||||
|
||||
b[2] = first_track;
|
||||
b[3] = last_track;
|
||||
|
||||
d = 0;
|
||||
for (c = 0; c <= last_track; c++)
|
||||
{
|
||||
cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr);
|
||||
if (number >= starttrack)
|
||||
{
|
||||
d=c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr);
|
||||
b[2] = number;
|
||||
|
||||
for (c = d; c <= last_track; c++)
|
||||
{
|
||||
if ((len + 8) > maxlen)
|
||||
break;
|
||||
cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr);
|
||||
|
||||
// pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame));
|
||||
b[len++] = 0; /* reserved */
|
||||
b[len++] = attr;
|
||||
b[len++] = number; /* track number */
|
||||
b[len++] = 0; /* reserved */
|
||||
|
||||
if (msf)
|
||||
{
|
||||
b[len++] = 0;
|
||||
b[len++] = tmsf.min;
|
||||
b[len++] = tmsf.sec;
|
||||
b[len++] = tmsf.fr;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150;
|
||||
b[len++] = temp >> 24;
|
||||
b[len++] = temp >> 16;
|
||||
b[len++] = temp >> 8;
|
||||
b[len++] = temp;
|
||||
}
|
||||
if (single)
|
||||
break;
|
||||
}
|
||||
b[0] = (uint8_t)(((len-2) >> 8) & 0xff);
|
||||
b[1] = (uint8_t)((len-2) & 0xff);
|
||||
/*
|
||||
pclog("Table of Contents:\n");
|
||||
pclog("First track - %02X\n", first_track);
|
||||
pclog("Last track - %02X\n", last_track);
|
||||
for (c = 0; c <= last_track; c++)
|
||||
{
|
||||
cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr);
|
||||
pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, number, attr, 0, 0, tmsf.min, tmsf.sec, tmsf.fr);
|
||||
}
|
||||
for (c = 0;c <= last_track; c++) {
|
||||
cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr);
|
||||
pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, number, attr, 0, MSF_TO_FRAMES(tmsf.min, tmsf.sec, tmsf.fr));
|
||||
}
|
||||
*/
|
||||
return len;
|
||||
}
|
||||
|
||||
static int image_readtoc_session(unsigned char *b, int msf, int maxlen)
|
||||
{
|
||||
if (!cdrom) return 0;
|
||||
int len = 4;
|
||||
|
||||
int number;
|
||||
TMSF tmsf;
|
||||
unsigned char attr;
|
||||
cdrom->GetAudioTrackInfo(1, number, tmsf, attr);
|
||||
|
||||
// pclog("Read TOC session - %i %02X %02X %i %i %02X %02X %02X\n",0, 0, 0,1,1,attr,0,number);
|
||||
|
||||
b[2] = 1;
|
||||
b[3] = 1;
|
||||
b[len++] = 0; /* reserved */
|
||||
b[len++] = attr;
|
||||
b[len++] = number; /* track number */
|
||||
b[len++] = 0; /* reserved */
|
||||
if (msf)
|
||||
{
|
||||
b[len++] = 0;
|
||||
b[len++] = tmsf.min;
|
||||
b[len++] = tmsf.sec;
|
||||
b[len++] = tmsf.fr;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150;
|
||||
b[len++] = temp >> 24;
|
||||
b[len++] = temp >> 16;
|
||||
b[len++] = temp >> 8;
|
||||
b[len++] = temp;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int image_readtoc_raw(unsigned char *b, int maxlen)
|
||||
{
|
||||
if (!cdrom) return 0;
|
||||
|
||||
int track;
|
||||
int len = 4;
|
||||
|
||||
int first_track;
|
||||
int last_track;
|
||||
int number;
|
||||
unsigned char attr;
|
||||
TMSF tmsf;
|
||||
cdrom->GetAudioTracks(first_track, last_track, tmsf);
|
||||
|
||||
b[2] = first_track;
|
||||
b[3] = last_track;
|
||||
|
||||
for (track = first_track; track <= last_track; track++)
|
||||
{
|
||||
if ((len + 11) > maxlen)
|
||||
{
|
||||
pclog("image_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n");
|
||||
return len;
|
||||
}
|
||||
|
||||
cdrom->GetAudioTrackInfo(track, number, tmsf, attr);
|
||||
|
||||
// pclog("read_toc: Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", track, toc[track].cdte_track, toc[track].cdte_ctrl, toc[track].cdte_adr, 0, toc[track].cdte_addr.msf.minute, toc[track].cdte_addr.msf.second, toc[track].cdte_addr.msf.frame);
|
||||
|
||||
b[len++] = track;
|
||||
b[len++]= attr;
|
||||
b[len++]=0;
|
||||
b[len++]=0;
|
||||
b[len++]=0;
|
||||
b[len++]=0;
|
||||
b[len++]=0;
|
||||
b[len++]=0;
|
||||
b[len++] = tmsf.min;
|
||||
b[len++] = tmsf.sec;
|
||||
b[len++] = tmsf.fr;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static uint32_t image_size()
|
||||
{
|
||||
return cdrom_capacity;
|
||||
}
|
||||
|
||||
static int image_status()
|
||||
{
|
||||
if (!cdrom) return CD_STATUS_EMPTY;
|
||||
if (cdrom->HasAudioTracks())
|
||||
{
|
||||
switch(image_cd_state)
|
||||
{
|
||||
case CD_PLAYING:
|
||||
return CD_STATUS_PLAYING;
|
||||
case CD_PAUSED:
|
||||
return CD_STATUS_PAUSED;
|
||||
case CD_STOPPED:
|
||||
default:
|
||||
return CD_STATUS_STOPPED;
|
||||
}
|
||||
}
|
||||
return CD_STATUS_DATA_ONLY;
|
||||
}
|
||||
void image_reset()
|
||||
{
|
||||
}
|
||||
|
||||
void image_close(void)
|
||||
{
|
||||
image_cd_state = CD_STOPPED;
|
||||
if (cdrom)
|
||||
{
|
||||
delete cdrom;
|
||||
cdrom = NULL;
|
||||
}
|
||||
// memset(image_path, 0, 1024);
|
||||
}
|
||||
|
||||
int image_open(char *fn)
|
||||
{
|
||||
if (strcmp(fn, image_path) != 0)
|
||||
image_changed = 1;
|
||||
|
||||
/* Make sure image_changed stays when changing from an image to another image. */
|
||||
if (cdrom_drive != CDROM_IMAGE)
|
||||
image_changed = 1;
|
||||
/* strcpy fails on OSX if both parameters are pointing to the same address */
|
||||
if (image_path != fn)
|
||||
strcpy(image_path, fn);
|
||||
|
||||
cdrom = new CDROM_Interface_Image();
|
||||
if (!cdrom->SetDevice(fn, false))
|
||||
{
|
||||
image_close();
|
||||
return 1;
|
||||
}
|
||||
image_cd_state = CD_STOPPED;
|
||||
image_cd_pos = 0;
|
||||
cd_buflen = 0;
|
||||
cdrom_capacity = image_get_last_block(0, 0, 4096, 0) + 1;
|
||||
atapi = &image_atapi;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void image_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
ATAPI image_atapi=
|
||||
{
|
||||
image_ready,
|
||||
image_medium_changed,
|
||||
image_readtoc,
|
||||
image_readtoc_session,
|
||||
image_readtoc_raw,
|
||||
image_getcurrentsubchannel,
|
||||
image_readsector,
|
||||
image_readsector_raw,
|
||||
image_playaudio,
|
||||
image_seek,
|
||||
image_load,
|
||||
image_eject,
|
||||
image_pause,
|
||||
image_resume,
|
||||
image_size,
|
||||
image_status,
|
||||
image_is_track_audio,
|
||||
image_stop,
|
||||
image_exit
|
||||
};
|
||||
23
src/cdrom-image.h
Normal file
23
src/cdrom-image.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef CDROM_ISO_H
|
||||
#define CDROM_ISO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern char image_path[1024];
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int image_open(char *fn);
|
||||
void image_reset();
|
||||
void image_close();
|
||||
|
||||
void image_audio_callback(int16_t *output, int len);
|
||||
void image_audio_stop();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! CDROM_ISO_H */
|
||||
|
|
@ -58,10 +58,7 @@ void ioctl_audio_callback(int16_t *output, int len)
|
|||
// return;
|
||||
// pclog("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, cd_buffer[4], GetTickCount());
|
||||
if (ioctl_cd_state != CD_PLAYING)
|
||||
{
|
||||
memset(output, 0, len * 2);
|
||||
return;
|
||||
}
|
||||
while (cd_buflen < len)
|
||||
{
|
||||
if (ioctl_cd_pos < ioctl_cd_end)
|
||||
|
|
|
|||
356
src/cdrom-iso.c
356
src/cdrom-iso.c
|
|
@ -1,356 +0,0 @@
|
|||
/*ISO CD-ROM support*/
|
||||
|
||||
#include "ibm.h"
|
||||
#include "ide.h"
|
||||
#include "cdrom-iso.h"
|
||||
#include <sys/stat.h>
|
||||
|
||||
static ATAPI iso_atapi;
|
||||
|
||||
static uint32_t last_block = 0;
|
||||
static uint64_t image_size = 0;
|
||||
static int iso_inited = 0;
|
||||
char iso_path[1024];
|
||||
void iso_close(void);
|
||||
static FILE *iso_image = NULL;
|
||||
static int iso_changed = 0;
|
||||
|
||||
void iso_audio_callback(int16_t *output, int len)
|
||||
{
|
||||
memset(output, 0, len * 2);
|
||||
return;
|
||||
}
|
||||
|
||||
void iso_audio_stop()
|
||||
{
|
||||
pclog("iso_audio_stop stub\n");
|
||||
}
|
||||
|
||||
static void iso_playaudio(uint32_t pos, uint32_t len, int ismsf)
|
||||
{
|
||||
pclog("iso_playaudio stub\n");
|
||||
return;
|
||||
}
|
||||
|
||||
static void iso_pause(void)
|
||||
{
|
||||
pclog("iso_pause stub\n");
|
||||
return;
|
||||
}
|
||||
|
||||
static void iso_resume(void)
|
||||
{
|
||||
pclog("iso_resume stub\n");
|
||||
return;
|
||||
}
|
||||
|
||||
static void iso_stop(void)
|
||||
{
|
||||
pclog("iso_stop stub\n");
|
||||
return;
|
||||
}
|
||||
|
||||
static void iso_seek(uint32_t pos)
|
||||
{
|
||||
pclog("iso_seek stub\n");
|
||||
return;
|
||||
}
|
||||
|
||||
static int iso_ready(void)
|
||||
{
|
||||
if (strlen(iso_path) == 0)
|
||||
return 0;
|
||||
|
||||
if (old_cdrom_drive != cdrom_drive)
|
||||
return 1;
|
||||
|
||||
iso_changed = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Always return 0, because there is no way to change the ISO without unmounting and remounting it. */
|
||||
static int iso_medium_changed(void)
|
||||
{
|
||||
iso_changed = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t iso_getcurrentsubchannel(uint8_t *b, int msf)
|
||||
{
|
||||
pclog("iso_getcurrentsubchannel stub\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void iso_eject(void)
|
||||
{
|
||||
pclog("iso_eject stub\n");
|
||||
}
|
||||
|
||||
static void iso_load(void)
|
||||
{
|
||||
pclog("iso_load stub\n");
|
||||
}
|
||||
|
||||
static int iso_readsector(uint8_t *b, int sector)
|
||||
{
|
||||
if (!cdrom_drive)
|
||||
return -1;
|
||||
fseek(iso_image,sector*2048,SEEK_SET);
|
||||
fread(b,2048,1,iso_image);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lba_to_msf(uint8_t *buf, int lba)
|
||||
{
|
||||
lba += 150;
|
||||
buf[0] = (lba / 75) / 60;
|
||||
buf[1] = (lba / 75) % 60;
|
||||
buf[2] = lba % 75;
|
||||
}
|
||||
|
||||
static void iso_readsector_raw(uint8_t *b, int sector)
|
||||
{
|
||||
if (!cdrom_drive) return;
|
||||
fseek(iso_image, sector*2048, SEEK_SET);
|
||||
fread(b+16, 2048, 1, iso_image);
|
||||
|
||||
/* sync bytes */
|
||||
b[0] = 0;
|
||||
memset(b + 1, 0xff, 10);
|
||||
b[11] = 0;
|
||||
b += 12;
|
||||
lba_to_msf(b, sector);
|
||||
b[3] = 1; /* mode 1 data */
|
||||
b += 4;
|
||||
b += 2048;
|
||||
memset(b, 0, 288);
|
||||
}
|
||||
|
||||
static int iso_readtoc(unsigned char *buf, unsigned char start_track, int msf, int maxlen, int single)
|
||||
{
|
||||
uint8_t *q;
|
||||
int len;
|
||||
|
||||
if (start_track > 1 && start_track != 0xaa)
|
||||
return -1;
|
||||
q = buf + 2;
|
||||
*q++ = 1; /* first session */
|
||||
*q++ = 1; /* last session */
|
||||
if (start_track <= 1)
|
||||
{
|
||||
*q++ = 0; /* reserved */
|
||||
*q++ = 0x14; /* ADR, control */
|
||||
*q++ = 1; /* track number */
|
||||
*q++ = 0; /* reserved */
|
||||
if (msf)
|
||||
{
|
||||
*q++ = 0; /* reserved */
|
||||
lba_to_msf(q, 0);
|
||||
q += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* sector 0 */
|
||||
*q++ = 0;
|
||||
*q++ = 0;
|
||||
*q++ = 0;
|
||||
*q++ = 0;
|
||||
}
|
||||
}
|
||||
/* lead out track */
|
||||
*q++ = 0; /* reserved */
|
||||
*q++ = 0x16; /* ADR, control */
|
||||
*q++ = 0xaa; /* track number */
|
||||
*q++ = 0; /* reserved */
|
||||
last_block = image_size >> 11;
|
||||
if (msf)
|
||||
{
|
||||
*q++ = 0; /* reserved */
|
||||
lba_to_msf(q, last_block);
|
||||
q += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
*q++ = last_block >> 24;
|
||||
*q++ = last_block >> 16;
|
||||
*q++ = last_block >> 8;
|
||||
*q++ = last_block;
|
||||
}
|
||||
len = q - buf;
|
||||
buf[0] = (uint8_t)(((len-2) >> 8) & 0xff);
|
||||
buf[1] = (uint8_t)((len-2) & 0xff);
|
||||
return len;
|
||||
}
|
||||
|
||||
static int iso_readtoc_session(unsigned char *buf, int msf, int maxlen)
|
||||
{
|
||||
uint8_t *q;
|
||||
|
||||
q = buf + 2;
|
||||
*q++ = 1; /* first session */
|
||||
*q++ = 1; /* last session */
|
||||
|
||||
*q++ = 1; /* session number */
|
||||
*q++ = 0x14; /* data track */
|
||||
*q++ = 0; /* track number */
|
||||
*q++ = 0xa0; /* lead-in */
|
||||
*q++ = 0; /* min */
|
||||
*q++ = 0; /* sec */
|
||||
*q++ = 0; /* frame */
|
||||
*q++ = 0;
|
||||
|
||||
return 12;
|
||||
}
|
||||
|
||||
static int iso_readtoc_raw(unsigned char *buf, int maxlen)
|
||||
{
|
||||
uint8_t *q;
|
||||
int len;
|
||||
|
||||
q = buf + 2;
|
||||
*q++ = 1; /* first session */
|
||||
*q++ = 1; /* last session */
|
||||
|
||||
*q++ = 1; /* session number */
|
||||
*q++ = 0x14; /* data track */
|
||||
*q++ = 0; /* track number */
|
||||
*q++ = 0xa0; /* lead-in */
|
||||
*q++ = 0; /* min */
|
||||
*q++ = 0; /* sec */
|
||||
*q++ = 0; /* frame */
|
||||
*q++ = 0;
|
||||
*q++ = 1; /* first track */
|
||||
*q++ = 0x00; /* disk type */
|
||||
*q++ = 0x00;
|
||||
|
||||
*q++ = 1; /* session number */
|
||||
*q++ = 0x14; /* data track */
|
||||
*q++ = 0; /* track number */
|
||||
*q++ = 0xa1;
|
||||
*q++ = 0; /* min */
|
||||
*q++ = 0; /* sec */
|
||||
*q++ = 0; /* frame */
|
||||
*q++ = 0;
|
||||
*q++ = 1; /* last track */
|
||||
*q++ = 0x00;
|
||||
*q++ = 0x00;
|
||||
|
||||
*q++ = 1; /* session number */
|
||||
*q++ = 0x14; /* data track */
|
||||
*q++ = 0; /* track number */
|
||||
*q++ = 0xa2; /* lead-out */
|
||||
*q++ = 0; /* min */
|
||||
*q++ = 0; /* sec */
|
||||
*q++ = 0; /* frame */
|
||||
last_block = image_size >> 11;
|
||||
/* this is raw, must be msf */
|
||||
*q++ = 0; /* reserved */
|
||||
lba_to_msf(q, last_block);
|
||||
q += 3;
|
||||
|
||||
*q++ = 1; /* session number */
|
||||
*q++ = 0x14; /* ADR, control */
|
||||
*q++ = 0; /* track number */
|
||||
*q++ = 1; /* point */
|
||||
*q++ = 0; /* min */
|
||||
*q++ = 0; /* sec */
|
||||
*q++ = 0; /* frame */
|
||||
/* same here */
|
||||
*q++ = 0;
|
||||
*q++ = 0;
|
||||
*q++ = 0;
|
||||
*q++ = 0;
|
||||
|
||||
len = q - buf;
|
||||
buf[0] = (uint8_t)(((len-2) >> 8) & 0xff);
|
||||
buf[1] = (uint8_t)((len-2) & 0xff);
|
||||
return len;
|
||||
}
|
||||
|
||||
static uint32_t iso_size()
|
||||
{
|
||||
unsigned char b[4096];
|
||||
|
||||
atapi->readtoc(b, 0, 0, 4096, 0);
|
||||
|
||||
return last_block;
|
||||
}
|
||||
|
||||
static int iso_status()
|
||||
{
|
||||
if (!(iso_ready()) && (cdrom_drive != 200))
|
||||
return CD_STATUS_EMPTY;
|
||||
|
||||
return CD_STATUS_DATA_ONLY;
|
||||
}
|
||||
|
||||
void iso_reset()
|
||||
{
|
||||
}
|
||||
|
||||
int iso_open(char *fn)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (iso_image)
|
||||
fclose(iso_image);
|
||||
|
||||
if (strcmp(fn, iso_path) != 0)
|
||||
iso_changed = 1;
|
||||
|
||||
/* Make sure iso_changed stays when changing from ISO to another ISO. */
|
||||
if (cdrom_drive != CDROM_ISO)
|
||||
iso_changed = 1;
|
||||
strcpy(iso_path, fn);
|
||||
|
||||
iso_image = fopen(iso_path, "rb");
|
||||
atapi = &iso_atapi;
|
||||
|
||||
stat(iso_path, &st);
|
||||
image_size = st.st_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void iso_close(void)
|
||||
{
|
||||
if (iso_image)
|
||||
{
|
||||
fclose(iso_image);
|
||||
iso_image = NULL;
|
||||
}
|
||||
memset(iso_path, 0, 1024);
|
||||
}
|
||||
|
||||
static void iso_exit(void)
|
||||
{
|
||||
iso_inited = 0;
|
||||
}
|
||||
|
||||
static int iso_is_track_audio(uint32_t pos, int ismsf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ATAPI iso_atapi =
|
||||
{
|
||||
iso_ready,
|
||||
iso_medium_changed,
|
||||
iso_readtoc,
|
||||
iso_readtoc_session,
|
||||
iso_readtoc_raw,
|
||||
iso_getcurrentsubchannel,
|
||||
iso_readsector,
|
||||
iso_readsector_raw,
|
||||
iso_playaudio,
|
||||
iso_seek,
|
||||
iso_load,
|
||||
iso_eject,
|
||||
iso_pause,
|
||||
iso_resume,
|
||||
iso_size,
|
||||
iso_status,
|
||||
iso_is_track_audio,
|
||||
iso_stop,
|
||||
iso_exit
|
||||
};
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
#ifndef CDROM_ISO_H
|
||||
#define CDROM_ISO_H
|
||||
|
||||
/* this header file lists the functions provided by
|
||||
various platform specific cdrom-ioctl files */
|
||||
|
||||
extern char iso_path[1024];
|
||||
|
||||
extern int iso_open(char *fn);
|
||||
extern void iso_reset();
|
||||
extern void iso_close();
|
||||
|
||||
#endif /* ! CDROM_ISO_H */
|
||||
172
src/dosbox/cdrom.h
Normal file
172
src/dosbox/cdrom.h
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2015 The DOSBox Team
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* Modified for use with PCem by bit */
|
||||
|
||||
#ifndef __CDROM_INTERFACE__
|
||||
#define __CDROM_INTERFACE__
|
||||
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
//#include "dosbox.h"
|
||||
//#include "mem.h"
|
||||
//#include "mixer.h"
|
||||
//#include "SDL.h"
|
||||
//#include "SDL_thread.h"
|
||||
|
||||
#include <stdint.h>
|
||||
typedef signed int Bits;
|
||||
typedef unsigned int Bitu;
|
||||
typedef int8_t Bit8s;
|
||||
typedef uint8_t Bit8u;
|
||||
typedef int16_t Bit16s;
|
||||
typedef uint16_t Bit16u;
|
||||
typedef int32_t Bit32s;
|
||||
typedef uint32_t Bit32u;
|
||||
|
||||
typedef size_t PhysPt;
|
||||
|
||||
#define RAW_SECTOR_SIZE 2352
|
||||
#define COOKED_SECTOR_SIZE 2048
|
||||
|
||||
#define DATA_TRACK 0x14
|
||||
#define AUDIO_TRACK 0x10
|
||||
|
||||
#define CD_FPS 75
|
||||
#define FRAMES_TO_MSF(f, M,S,F) { \
|
||||
int value = f; \
|
||||
*(F) = value%CD_FPS; \
|
||||
value /= CD_FPS; \
|
||||
*(S) = value%60; \
|
||||
value /= 60; \
|
||||
*(M) = value; \
|
||||
}
|
||||
#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F))
|
||||
|
||||
|
||||
typedef struct SMSF {
|
||||
unsigned char min;
|
||||
unsigned char sec;
|
||||
unsigned char fr;
|
||||
} TMSF;
|
||||
|
||||
typedef struct SCtrl {
|
||||
Bit8u out[4]; // output channel
|
||||
Bit8u vol[4]; // channel volume
|
||||
} TCtrl;
|
||||
|
||||
extern int CDROM_GetMountType(char* path, int force);
|
||||
|
||||
class CDROM_Interface
|
||||
{
|
||||
public:
|
||||
// CDROM_Interface (void);
|
||||
virtual ~CDROM_Interface (void) {};
|
||||
|
||||
virtual bool SetDevice (char* path, int forceCD) = 0;
|
||||
|
||||
virtual bool GetUPC (unsigned char& attr, char* upc) = 0;
|
||||
|
||||
virtual bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) = 0;
|
||||
virtual bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr) = 0;
|
||||
virtual bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) = 0;
|
||||
virtual bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) = 0;
|
||||
|
||||
virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0;
|
||||
|
||||
virtual bool LoadUnloadMedia (bool unload) = 0;
|
||||
|
||||
virtual void InitNewMedia (void) {};
|
||||
};
|
||||
|
||||
class CDROM_Interface_Image : public CDROM_Interface
|
||||
{
|
||||
private:
|
||||
class TrackFile {
|
||||
public:
|
||||
virtual bool read(Bit8u *buffer, int seek, int count) = 0;
|
||||
virtual int getLength() = 0;
|
||||
virtual ~TrackFile() { };
|
||||
};
|
||||
|
||||
class BinaryFile : public TrackFile {
|
||||
public:
|
||||
BinaryFile(const char *filename, bool &error);
|
||||
~BinaryFile();
|
||||
bool read(Bit8u *buffer, int seek, int count);
|
||||
int getLength();
|
||||
private:
|
||||
BinaryFile();
|
||||
std::ifstream *file;
|
||||
};
|
||||
|
||||
struct Track {
|
||||
int number;
|
||||
int track_number;
|
||||
int attr;
|
||||
int start;
|
||||
int length;
|
||||
int skip;
|
||||
int sectorSize;
|
||||
bool mode2;
|
||||
TrackFile *file;
|
||||
};
|
||||
|
||||
public:
|
||||
CDROM_Interface_Image ();
|
||||
virtual ~CDROM_Interface_Image (void);
|
||||
void InitNewMedia (void);
|
||||
bool SetDevice (char* path, int forceCD);
|
||||
bool GetUPC (unsigned char& attr, char* upc);
|
||||
bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut);
|
||||
bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr);
|
||||
bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos);
|
||||
bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen);
|
||||
bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num);
|
||||
bool LoadUnloadMedia (bool unload);
|
||||
bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector);
|
||||
bool HasDataTrack (void);
|
||||
bool HasAudioTracks (void);
|
||||
|
||||
int GetTrack (int sector);
|
||||
|
||||
private:
|
||||
// player
|
||||
static void CDAudioCallBack(Bitu len);
|
||||
|
||||
void ClearTracks();
|
||||
bool LoadIsoFile(char *filename);
|
||||
bool CanReadPVD(TrackFile *file, int sectorSize, bool mode2);
|
||||
// cue sheet processing
|
||||
bool LoadCueSheet(char *cuefile);
|
||||
bool GetRealFileName(std::string& filename, std::string& pathname);
|
||||
bool GetCueKeyword(std::string &keyword, std::istream &in);
|
||||
bool GetCueFrame(int &frames, std::istream &in);
|
||||
bool GetCueString(std::string &str, std::istream &in);
|
||||
bool AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap);
|
||||
|
||||
std::vector<Track> tracks;
|
||||
typedef std::vector<Track>::iterator track_it;
|
||||
std::string mcn;
|
||||
};
|
||||
|
||||
#endif /* __CDROM_INTERFACE__ */
|
||||
546
src/dosbox/cdrom_image.cpp
Normal file
546
src/dosbox/cdrom_image.cpp
Normal file
|
|
@ -0,0 +1,546 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2015 The DOSBox Team
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* Modified for use with PCem by bit */
|
||||
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <limits.h> //GCC 2.95
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <sys/stat.h>
|
||||
#include "cdrom.h"
|
||||
|
||||
#if !defined(WIN32)
|
||||
#include <libgen.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define MAX_LINE_LENGTH 512
|
||||
#define MAX_FILENAME_LENGTH 256
|
||||
#define CROSS_LEN 512
|
||||
|
||||
#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0)
|
||||
|
||||
CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error)
|
||||
{
|
||||
file = new ifstream(filename, ios::in | ios::binary);
|
||||
error = (file == NULL) || (file->fail());
|
||||
}
|
||||
|
||||
CDROM_Interface_Image::BinaryFile::~BinaryFile()
|
||||
{
|
||||
delete file;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count)
|
||||
{
|
||||
file->seekg(seek, ios::beg);
|
||||
file->read((char*)buffer, count);
|
||||
return !(file->fail());
|
||||
}
|
||||
|
||||
int CDROM_Interface_Image::BinaryFile::getLength()
|
||||
{
|
||||
file->seekg(0, ios::end);
|
||||
int length = (int)file->tellg();
|
||||
if (file->fail()) return -1;
|
||||
return length;
|
||||
}
|
||||
|
||||
CDROM_Interface_Image::CDROM_Interface_Image()
|
||||
{
|
||||
}
|
||||
|
||||
CDROM_Interface_Image::~CDROM_Interface_Image()
|
||||
{
|
||||
ClearTracks();
|
||||
}
|
||||
|
||||
void CDROM_Interface_Image::InitNewMedia()
|
||||
{
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::SetDevice(char* path, int forceCD)
|
||||
{
|
||||
if (LoadCueSheet(path)) return true;
|
||||
if (LoadIsoFile(path)) return true;
|
||||
|
||||
// print error message on dosbox console
|
||||
//printf("Could not load image file: %s\n", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetUPC(unsigned char& attr, char* upc)
|
||||
{
|
||||
attr = 0;
|
||||
strcpy(upc, this->mcn.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut)
|
||||
{
|
||||
stTrack = 1;
|
||||
end = (int)(tracks.size() - 1);
|
||||
FRAMES_TO_MSF(tracks[tracks.size() - 1].start + 150, &leadOut.min, &leadOut.sec, &leadOut.fr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetAudioTrackInfo(int track, int& track_number, TMSF& start, unsigned char& attr)
|
||||
{
|
||||
if (track < 1 || track > (int)tracks.size()) return false;
|
||||
FRAMES_TO_MSF(tracks[track - 1].start + 150, &start.min, &start.sec, &start.fr);
|
||||
track_number = tracks[track - 1].track_number;
|
||||
attr = tracks[track - 1].attr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetAudioSub(int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos)
|
||||
{
|
||||
int cur_track = GetTrack(sector);
|
||||
if (cur_track < 1) return false;
|
||||
track = (unsigned char)cur_track;
|
||||
attr = tracks[track - 1].attr;
|
||||
index = 1;
|
||||
FRAMES_TO_MSF(sector + 150, &absPos.min, &absPos.sec, &absPos.fr);
|
||||
FRAMES_TO_MSF(sector - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen)
|
||||
{
|
||||
mediaPresent = true;
|
||||
mediaChanged = false;
|
||||
trayOpen = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num)
|
||||
{
|
||||
int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
|
||||
Bitu buflen = num * sectorSize;
|
||||
Bit8u* buf = new Bit8u[buflen];
|
||||
|
||||
bool success = true; //Gobliiins reads 0 sectors
|
||||
for(unsigned long i = 0; i < num; i++) {
|
||||
success = ReadSector(&buf[i * sectorSize], raw, sector + i);
|
||||
if (!success) break;
|
||||
}
|
||||
|
||||
memcpy((void*)buffer, buf, buflen);
|
||||
delete[] buf;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::LoadUnloadMedia(bool unload)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int CDROM_Interface_Image::GetTrack(int sector)
|
||||
{
|
||||
vector<Track>::iterator i = tracks.begin();
|
||||
vector<Track>::iterator end = tracks.end() - 1;
|
||||
|
||||
while(i != end) {
|
||||
Track &curr = *i;
|
||||
Track &next = *(i + 1);
|
||||
if (curr.start <= sector && sector < next.start) return curr.number;
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long sector)
|
||||
{
|
||||
int track = GetTrack(sector) - 1;
|
||||
if (track < 0) return false;
|
||||
|
||||
int seek = tracks[track].skip + (sector - tracks[track].start) * tracks[track].sectorSize;
|
||||
int length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE);
|
||||
if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false;
|
||||
if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16;
|
||||
if (tracks[track].mode2 && !raw) seek += 24;
|
||||
|
||||
return tracks[track].file->read(buffer, seek, length);
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::LoadIsoFile(char* filename)
|
||||
{
|
||||
tracks.clear();
|
||||
|
||||
// data track
|
||||
Track track = {0, 0, 0, 0, 0, 0, 0, false, NULL};
|
||||
bool error;
|
||||
track.file = new BinaryFile(filename, error);
|
||||
if (error) {
|
||||
delete track.file;
|
||||
return false;
|
||||
}
|
||||
track.number = 1;
|
||||
track.track_number = 1;
|
||||
track.attr = DATA_TRACK;//data
|
||||
|
||||
// try to detect iso type
|
||||
if (CanReadPVD(track.file, COOKED_SECTOR_SIZE, false)) {
|
||||
track.sectorSize = COOKED_SECTOR_SIZE;
|
||||
track.mode2 = false;
|
||||
} else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, false)) {
|
||||
track.sectorSize = RAW_SECTOR_SIZE;
|
||||
track.mode2 = false;
|
||||
} else if (CanReadPVD(track.file, 2336, true)) {
|
||||
track.sectorSize = 2336;
|
||||
track.mode2 = true;
|
||||
} else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, true)) {
|
||||
track.sectorSize = RAW_SECTOR_SIZE;
|
||||
track.mode2 = true;
|
||||
} else return false;
|
||||
|
||||
track.length = track.file->getLength() / track.sectorSize;
|
||||
tracks.push_back(track);
|
||||
|
||||
// leadout track
|
||||
track.number = 2;
|
||||
track.track_number = 0xAA;
|
||||
track.attr = 0;
|
||||
track.start = track.length;
|
||||
track.length = 0;
|
||||
track.file = NULL;
|
||||
tracks.push_back(track);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mode2)
|
||||
{
|
||||
Bit8u pvd[COOKED_SECTOR_SIZE];
|
||||
int seek = 16 * sectorSize; // first vd is located at sector 16
|
||||
if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16;
|
||||
if (mode2) seek += 24;
|
||||
file->read(pvd, seek, COOKED_SECTOR_SIZE);
|
||||
// pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version (+8 for High Sierra)
|
||||
return ((pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1) ||
|
||||
(pvd[8] == 1 && !strncmp((char*)(&pvd[9]), "CDROM", 5) && pvd[14] == 1));
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
static string dirname(char * file) {
|
||||
char * sep = strrchr(file, '\\');
|
||||
if (sep == NULL)
|
||||
sep = strrchr(file, '/');
|
||||
if (sep == NULL)
|
||||
return "";
|
||||
else {
|
||||
int len = (int)(sep - file);
|
||||
char tmp[MAX_FILENAME_LENGTH];
|
||||
safe_strncpy(tmp, file, len+1);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool CDROM_Interface_Image::LoadCueSheet(char *cuefile)
|
||||
{
|
||||
Track track = {0, 0, 0, 0, 0, 0, 0, false, NULL};
|
||||
tracks.clear();
|
||||
int shift = 0;
|
||||
int currPregap = 0;
|
||||
int totalPregap = 0;
|
||||
int prestart = 0;
|
||||
bool success;
|
||||
bool canAddTrack = false;
|
||||
char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument
|
||||
safe_strncpy(tmp, cuefile, MAX_FILENAME_LENGTH);
|
||||
string pathname(dirname(tmp));
|
||||
ifstream in;
|
||||
in.open(cuefile, ios::in);
|
||||
if (in.fail()) return false;
|
||||
|
||||
while(!in.eof()) {
|
||||
// get next line
|
||||
char buf[MAX_LINE_LENGTH];
|
||||
in.getline(buf, MAX_LINE_LENGTH);
|
||||
if (in.fail() && !in.eof()) return false; // probably a binary file
|
||||
istringstream line(buf);
|
||||
|
||||
string command;
|
||||
GetCueKeyword(command, line);
|
||||
|
||||
if (command == "TRACK") {
|
||||
if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap);
|
||||
else success = true;
|
||||
|
||||
track.start = 0;
|
||||
track.skip = 0;
|
||||
currPregap = 0;
|
||||
prestart = 0;
|
||||
|
||||
line >> track.number;
|
||||
track.track_number = track.number;
|
||||
string type;
|
||||
GetCueKeyword(type, line);
|
||||
|
||||
if (type == "AUDIO") {
|
||||
track.sectorSize = RAW_SECTOR_SIZE;
|
||||
track.attr = AUDIO_TRACK;
|
||||
track.mode2 = false;
|
||||
} else if (type == "MODE1/2048") {
|
||||
track.sectorSize = COOKED_SECTOR_SIZE;
|
||||
track.attr = DATA_TRACK;
|
||||
track.mode2 = false;
|
||||
} else if (type == "MODE1/2352") {
|
||||
track.sectorSize = RAW_SECTOR_SIZE;
|
||||
track.attr = DATA_TRACK;
|
||||
track.mode2 = false;
|
||||
} else if (type == "MODE2/2336") {
|
||||
track.sectorSize = 2336;
|
||||
track.attr = DATA_TRACK;
|
||||
track.mode2 = true;
|
||||
} else if (type == "MODE2/2352") {
|
||||
track.sectorSize = RAW_SECTOR_SIZE;
|
||||
track.attr = DATA_TRACK;
|
||||
track.mode2 = true;
|
||||
} else success = false;
|
||||
|
||||
canAddTrack = true;
|
||||
}
|
||||
else if (command == "INDEX") {
|
||||
int index;
|
||||
line >> index;
|
||||
int frame;
|
||||
success = GetCueFrame(frame, line);
|
||||
|
||||
if (index == 1) track.start = frame;
|
||||
else if (index == 0) prestart = frame;
|
||||
// ignore other indices
|
||||
}
|
||||
else if (command == "FILE") {
|
||||
if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap);
|
||||
else success = true;
|
||||
canAddTrack = false;
|
||||
|
||||
string filename;
|
||||
GetCueString(filename, line);
|
||||
GetRealFileName(filename, pathname);
|
||||
string type;
|
||||
GetCueKeyword(type, line);
|
||||
|
||||
track.file = NULL;
|
||||
bool error = true;
|
||||
if (type == "BINARY") {
|
||||
track.file = new BinaryFile(filename.c_str(), error);
|
||||
}
|
||||
if (error) {
|
||||
delete track.file;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
else if (command == "PREGAP") success = GetCueFrame(currPregap, line);
|
||||
else if (command == "CATALOG") success = GetCueString(mcn, line);
|
||||
// ignored commands
|
||||
else if (command == "CDTEXTFILE" || command == "FLAGS" || command == "ISRC"
|
||||
|| command == "PERFORMER" || command == "POSTGAP" || command == "REM"
|
||||
|| command == "SONGWRITER" || command == "TITLE" || command == "") success = true;
|
||||
// failure
|
||||
else success = false;
|
||||
|
||||
if (!success) return false;
|
||||
}
|
||||
// add last track
|
||||
if (!AddTrack(track, shift, prestart, totalPregap, currPregap)) return false;
|
||||
|
||||
// add leadout track
|
||||
track.number++;
|
||||
track.track_number = 0xAA;
|
||||
track.attr = 0;//sync with load iso
|
||||
track.start = 0;
|
||||
track.length = 0;
|
||||
track.file = NULL;
|
||||
if(!AddTrack(track, shift, 0, totalPregap, 0)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap)
|
||||
{
|
||||
// frames between index 0(prestart) and 1(curr.start) must be skipped
|
||||
int skip;
|
||||
if (prestart > 0) {
|
||||
if (prestart > curr.start) return false;
|
||||
skip = curr.start - prestart;
|
||||
} else skip = 0;
|
||||
|
||||
// first track (track number must be 1)
|
||||
if (tracks.empty()) {
|
||||
if (curr.number != 1) return false;
|
||||
curr.skip = skip * curr.sectorSize;
|
||||
curr.start += currPregap;
|
||||
totalPregap = currPregap;
|
||||
tracks.push_back(curr);
|
||||
return true;
|
||||
}
|
||||
|
||||
Track &prev = *(tracks.end() - 1);
|
||||
|
||||
// current track consumes data from the same file as the previous
|
||||
if (prev.file == curr.file) {
|
||||
curr.start += shift;
|
||||
prev.length = curr.start + totalPregap - prev.start - skip;
|
||||
curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize;
|
||||
totalPregap += currPregap;
|
||||
curr.start += totalPregap;
|
||||
// current track uses a different file as the previous track
|
||||
} else {
|
||||
int tmp = prev.file->getLength() - prev.skip;
|
||||
prev.length = tmp / prev.sectorSize;
|
||||
if (tmp % prev.sectorSize != 0) prev.length++; // padding
|
||||
|
||||
curr.start += prev.start + prev.length + currPregap;
|
||||
curr.skip = skip * curr.sectorSize;
|
||||
shift += prev.start + prev.length;
|
||||
totalPregap = currPregap;
|
||||
}
|
||||
|
||||
// error checks
|
||||
if (curr.number <= 1) return false;
|
||||
if (prev.number + 1 != curr.number) return false;
|
||||
if (curr.start < prev.start + prev.length) return false;
|
||||
if (curr.length < 0) return false;
|
||||
|
||||
tracks.push_back(curr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::HasDataTrack(void)
|
||||
{
|
||||
//Data track has attribute 0x14
|
||||
for(track_it it = tracks.begin(); it != tracks.end(); it++) {
|
||||
if ((*it).attr == DATA_TRACK) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::HasAudioTracks(void)
|
||||
{
|
||||
for(track_it it = tracks.begin(); it != tracks.end(); it++) {
|
||||
if ((*it).attr == AUDIO_TRACK) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname)
|
||||
{
|
||||
// check if file exists
|
||||
struct stat test;
|
||||
if (stat(filename.c_str(), &test) == 0) return true;
|
||||
|
||||
// check if file with path relative to cue file exists
|
||||
string tmpstr(pathname + "/" + filename);
|
||||
if (stat(tmpstr.c_str(), &test) == 0) {
|
||||
filename = tmpstr;
|
||||
return true;
|
||||
}
|
||||
#if defined (WIN32) || defined(OS2)
|
||||
//Nothing
|
||||
#else
|
||||
//Consider the possibility that the filename has a windows directory seperator (inside the CUE file)
|
||||
//which is common for some commercial rereleases of DOS games using DOSBox
|
||||
|
||||
string copy = filename;
|
||||
size_t l = copy.size();
|
||||
for (size_t i = 0; i < l;i++) {
|
||||
if(copy[i] == '\\') copy[i] = '/';
|
||||
}
|
||||
|
||||
if (stat(copy.c_str(), &test) == 0) {
|
||||
filename = copy;
|
||||
return true;
|
||||
}
|
||||
|
||||
tmpstr = pathname + "/" + copy;
|
||||
if (stat(tmpstr.c_str(), &test) == 0) {
|
||||
filename = tmpstr;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in)
|
||||
{
|
||||
in >> keyword;
|
||||
for(Bitu i = 0; i < keyword.size(); i++) keyword[i] = toupper(keyword[i]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in)
|
||||
{
|
||||
string msf;
|
||||
in >> msf;
|
||||
int min, sec, fr;
|
||||
bool success = sscanf(msf.c_str(), "%d:%d:%d", &min, &sec, &fr) == 3;
|
||||
frames = MSF_TO_FRAMES(min, sec, fr);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetCueString(string &str, istream &in)
|
||||
{
|
||||
int pos = (int)in.tellg();
|
||||
in >> str;
|
||||
if (str[0] == '\"') {
|
||||
if (str[str.size() - 1] == '\"') {
|
||||
str.assign(str, 1, str.size() - 2);
|
||||
} else {
|
||||
in.seekg(pos, ios::beg);
|
||||
char buffer[MAX_FILENAME_LENGTH];
|
||||
in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); // skip
|
||||
in.getline(buffer, MAX_FILENAME_LENGTH, '\"');
|
||||
str = buffer;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDROM_Interface_Image::ClearTracks()
|
||||
{
|
||||
vector<Track>::iterator i = tracks.begin();
|
||||
vector<Track>::iterator end = tracks.end();
|
||||
|
||||
TrackFile* last = NULL;
|
||||
while(i != end) {
|
||||
Track &curr = *i;
|
||||
if (curr.file != last) {
|
||||
delete curr.file;
|
||||
last = curr.file;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
tracks.clear();
|
||||
}
|
||||
|
|
@ -167,7 +167,7 @@ struct
|
|||
|
||||
#define cycles cpu_state._cycles
|
||||
|
||||
uint32_t cpu_cur_status;
|
||||
extern uint32_t cpu_cur_status;
|
||||
|
||||
#define CPU_STATUS_USE32 (1 << 0)
|
||||
#define CPU_STATUS_STACK32 (1 << 1)
|
||||
|
|
|
|||
|
|
@ -2415,7 +2415,7 @@ static void atapicommand(int ide_board)
|
|||
}
|
||||
|
||||
|
||||
if ((cdrom_drive < 1) || (cdrom_drive == CDROM_ISO) || (cd_status <= CD_STATUS_DATA_ONLY) ||
|
||||
if ((cdrom_drive < 1) || (cd_status <= CD_STATUS_DATA_ONLY) ||
|
||||
!atapi->is_track_audio(pos, (idebufferb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0))
|
||||
{
|
||||
ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/
|
||||
|
|
|
|||
|
|
@ -56,6 +56,6 @@ extern int cdrom_channel;
|
|||
uint32_t atapi_get_cd_channel(int channel);
|
||||
uint32_t atapi_get_cd_volume(int channel);
|
||||
|
||||
#define CDROM_ISO 200
|
||||
#define CDROM_IMAGE 200
|
||||
|
||||
#endif //__IDE__
|
||||
|
|
|
|||
38
src/pc.c
38
src/pc.c
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "ali1429.h"
|
||||
#include "cdrom-ioctl.h"
|
||||
#include "cdrom-iso.h"
|
||||
#include "cdrom-image.h"
|
||||
#include "disc.h"
|
||||
#include "disc_img.h"
|
||||
#include "mem.h"
|
||||
|
|
@ -281,13 +281,13 @@ void initpc(int argc, char *argv[])
|
|||
else
|
||||
#endif
|
||||
{
|
||||
if (cdrom_drive == CDROM_ISO)
|
||||
if (cdrom_drive == CDROM_IMAGE)
|
||||
{
|
||||
FILE *ff = fopen(iso_path, "rb");
|
||||
FILE *ff = fopen(image_path, "rb");
|
||||
if (ff)
|
||||
{
|
||||
fclose(ff);
|
||||
iso_open(iso_path);
|
||||
image_open(image_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -318,9 +318,9 @@ void initpc(int argc, char *argv[])
|
|||
else
|
||||
#endif
|
||||
{
|
||||
if (cdrom_drive == CDROM_ISO)
|
||||
if (cdrom_drive == CDROM_IMAGE)
|
||||
{
|
||||
iso_reset();
|
||||
image_reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -398,15 +398,31 @@ void resetpchard()
|
|||
|
||||
// output=3;
|
||||
|
||||
image_close();
|
||||
#if __unix
|
||||
if (cdrom_drive == -1)
|
||||
cdrom_null_reset();
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (cdrom_drive == CDROM_ISO)
|
||||
if (cdrom_drive == CDROM_IMAGE)
|
||||
{
|
||||
iso_reset();
|
||||
FILE *ff = fopen(image_path, "rb");
|
||||
if (ff)
|
||||
{
|
||||
fclose(ff);
|
||||
image_open(image_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if __unix
|
||||
cdrom_drive = -1;
|
||||
cdrom_null_open(cdrom_drive);
|
||||
#else
|
||||
cdrom_drive = 0;
|
||||
ioctl_set_drive(cdrom_drive);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -655,8 +671,8 @@ void loadconfig(char *fn)
|
|||
cdrom_channel = config_get_int(CFG_MACHINE, NULL, "cdrom_channel", 2);
|
||||
|
||||
p = (char *)config_get_string(CFG_MACHINE, NULL, "cdrom_path", "");
|
||||
if (p) strcpy(iso_path, p);
|
||||
else strcpy(iso_path, "");
|
||||
if (p) strcpy(image_path, p);
|
||||
else strcpy(image_path, "");
|
||||
|
||||
hdc[0].spt = config_get_int(CFG_MACHINE, NULL, "hdc_sectors", 0);
|
||||
hdc[0].hpc = config_get_int(CFG_MACHINE, NULL, "hdc_heads", 0);
|
||||
|
|
@ -764,7 +780,7 @@ void saveconfig(char *fn)
|
|||
config_set_int(CFG_MACHINE, NULL, "cdrom_drive", cdrom_drive);
|
||||
config_set_int(CFG_MACHINE, NULL, "cdrom_enabled", cdrom_enabled);
|
||||
config_set_int(CFG_MACHINE, NULL, "cdrom_channel", cdrom_channel);
|
||||
config_set_string(CFG_MACHINE, NULL, "cdrom_path", iso_path);
|
||||
config_set_string(CFG_MACHINE, NULL, "cdrom_path", image_path);
|
||||
|
||||
config_set_int(CFG_MACHINE, NULL, "hdc_sectors", hdc[0].spt);
|
||||
config_set_int(CFG_MACHINE, NULL, "hdc_heads", hdc[0].hpc);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ BEGIN
|
|||
BEGIN
|
||||
MENUITEM "&Disabled", IDM_CDROM_DISABLED
|
||||
MENUITEM "&Empty",IDM_CDROM_EMPTY
|
||||
MENUITEM "&ISO...",IDM_CDROM_ISO
|
||||
MENUITEM "&Image...",IDM_CDROM_IMAGE
|
||||
END
|
||||
POPUP "&Video"
|
||||
BEGIN
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#define IDM_CDROM_EMPTY 40100
|
||||
#define IDM_CDROM_REAL 40100
|
||||
#define IDM_CDROM_DISABLED 40200
|
||||
#define IDM_CDROM_ISO 40201
|
||||
#define IDM_CDROM_IMAGE 40201
|
||||
|
||||
#define IDC_COMBO1 1000
|
||||
#define IDC_COMBOVID 1001
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "device.h"
|
||||
|
||||
#include "cdrom-ioctl.h"
|
||||
#include "cdrom-image.h"
|
||||
#include "ide.h"
|
||||
|
||||
#include "filters.h"
|
||||
|
|
@ -134,7 +135,9 @@ static void sound_cd_thread(void *param)
|
|||
int c;
|
||||
|
||||
thread_wait_event(sound_cd_event, -1);
|
||||
memset(cd_buffer, 0, CD_BUFLEN*2 * 2);
|
||||
ioctl_audio_callback(cd_buffer, CD_BUFLEN*2);
|
||||
image_audio_callback(cd_buffer, CD_BUFLEN*2);
|
||||
if (soundon)
|
||||
{
|
||||
int32_t atapi_vol_l = atapi_get_cd_volume(0);
|
||||
|
|
@ -259,4 +262,5 @@ void sound_reset()
|
|||
|
||||
sound_set_cd_volume(65535, 65535);
|
||||
ioctl_audio_stop();
|
||||
image_audio_stop();
|
||||
}
|
||||
|
|
|
|||
34
src/win.c
34
src/win.c
|
|
@ -15,7 +15,7 @@
|
|||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "cdrom-ioctl.h"
|
||||
#include "cdrom-iso.h"
|
||||
#include "cdrom-image.h"
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include "device.h"
|
||||
|
|
@ -632,8 +632,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
|
|||
CheckMenuItem(menu, IDM_CDROM_DISABLED, MF_CHECKED);
|
||||
else
|
||||
{
|
||||
if (cdrom_drive == CDROM_ISO)
|
||||
CheckMenuItem(menu, IDM_CDROM_ISO, MF_CHECKED);
|
||||
if (cdrom_drive == CDROM_IMAGE)
|
||||
CheckMenuItem(menu, IDM_CDROM_IMAGE, MF_CHECKED);
|
||||
else
|
||||
CheckMenuItem(menu, IDM_CDROM_REAL + cdrom_drive, MF_CHECKED);
|
||||
}
|
||||
|
|
@ -885,8 +885,8 @@ void atapi_close(void)
|
|||
{
|
||||
switch (cdrom_drive)
|
||||
{
|
||||
case CDROM_ISO:
|
||||
iso_close();
|
||||
case CDROM_IMAGE:
|
||||
image_close();
|
||||
break;
|
||||
default:
|
||||
ioctl_close();
|
||||
|
|
@ -898,7 +898,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
{
|
||||
HMENU hmenu;
|
||||
RECT rect;
|
||||
char temp_iso_path[1024];
|
||||
char temp_image_path[1024];
|
||||
int new_cdrom_drive;
|
||||
// pclog("Message %i %08X\n",message,message);
|
||||
switch (message)
|
||||
|
|
@ -1067,7 +1067,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
ioctl_set_drive(0);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_CHECKED);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_UNCHECKED);
|
||||
old_cdrom_drive = cdrom_drive;
|
||||
cdrom_drive=0;
|
||||
CheckMenuItem(hmenu, IDM_CDROM_EMPTY, MF_UNCHECKED);
|
||||
|
|
@ -1103,7 +1103,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
}
|
||||
CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_UNCHECKED);
|
||||
old_cdrom_drive = cdrom_drive;
|
||||
cdrom_drive=0;
|
||||
CheckMenuItem(hmenu, IDM_CDROM_EMPTY, MF_CHECKED);
|
||||
|
|
@ -1119,8 +1119,8 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
}
|
||||
break;
|
||||
|
||||
case IDM_CDROM_ISO:
|
||||
if (!getfile(hwnd,"CD-ROM image (*.ISO)\0*.ISO\0All files (*.*)\0*.*\0",iso_path))
|
||||
case IDM_CDROM_IMAGE:
|
||||
if (!getfile(hwnd,"CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0",image_path))
|
||||
{
|
||||
if (!cdrom_enabled)
|
||||
{
|
||||
|
|
@ -1128,15 +1128,15 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
break;
|
||||
}
|
||||
old_cdrom_drive = cdrom_drive;
|
||||
strcpy(temp_iso_path, openfilestring);
|
||||
if ((strcmp(iso_path, temp_iso_path) == 0) && (cdrom_drive == CDROM_ISO) && cdrom_enabled)
|
||||
strcpy(temp_image_path, openfilestring);
|
||||
if ((strcmp(image_path, temp_image_path) == 0) && (cdrom_drive == CDROM_IMAGE) && cdrom_enabled)
|
||||
{
|
||||
/* Switching from ISO to the same ISO. Do nothing. */
|
||||
break;
|
||||
}
|
||||
atapi->exit();
|
||||
atapi_close();
|
||||
iso_open(temp_iso_path);
|
||||
image_open(temp_image_path);
|
||||
if (cdrom_enabled)
|
||||
{
|
||||
/* Signal disc change to the emulated machine. */
|
||||
|
|
@ -1144,9 +1144,9 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
}
|
||||
CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED);
|
||||
cdrom_drive = CDROM_ISO;
|
||||
CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_CHECKED);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_UNCHECKED);
|
||||
cdrom_drive = CDROM_IMAGE;
|
||||
CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_CHECKED);
|
||||
saveconfig(NULL);
|
||||
if (!cdrom_enabled)
|
||||
{
|
||||
|
|
@ -1185,7 +1185,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
}
|
||||
CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_UNCHECKED);
|
||||
cdrom_drive = new_cdrom_drive;
|
||||
CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_CHECKED);
|
||||
saveconfig(NULL);
|
||||
|
|
|
|||
Loading…
Reference in a new issue