static int statusfunc (int status)
{
- if (status < 0)
- return 1000;
+ if (status == -1)
+ return 0;
+ if (status == -2)
+ return 150;
if (cdrom_audiostatus != status) {
if (status == AUDIO_STATUS_IN_PROGRESS) {
cdrom_playing = 1;
#include "scsidev.h"
#include "savestate.h"
#include "crc32.h"
+#include "threaddep/thread.h"
+#include "execio.h"
#ifdef RETROPLATFORM
#include "rp.h"
#endif
+int log_scsiemu = 0;
+
#define PRE_INSERT_DELAY (3 * (currprefs.ntscmode ? 60 : 50))
static int scsiemu[MAX_TOTAL_SCSI_DEVICES];
static int openlist[MAX_TOTAL_SCSI_DEVICES];
static int waspaused[MAX_TOTAL_SCSI_DEVICES];
static int delayed[MAX_TOTAL_SCSI_DEVICES];
+static uae_sem_t unitsem[MAX_TOTAL_SCSI_DEVICES];
+static int unitsem_cnt[MAX_TOTAL_SCSI_DEVICES];
/* convert minutes, seconds and frames -> logical sector number */
int msf2lsn (int msf)
}
+static bool getsem (int unitnum, bool dowait)
+{
+ if (unitsem[unitnum] == NULL)
+ uae_sem_init (&unitsem[unitnum], 0, 1);
+ bool gotit = false;
+ if (dowait) {
+ uae_sem_wait (&unitsem[unitnum]);
+ gotit = true;
+ } else {
+ gotit = uae_sem_trywait (&unitsem[unitnum]) == 0;
+ }
+ if (gotit)
+ unitsem_cnt[unitnum]++;
+ if (unitsem_cnt[unitnum] > 1)
+ write_log (L"CD: unitsem%d acquire mismatch! cnt=%d\n", unitnum, unitsem_cnt[unitnum]);
+ return gotit;
+}
+static bool getsem (int unitnum)
+{
+ return getsem (unitnum, false);
+}
+static void freesem (int unitnum)
+{
+ unitsem_cnt[unitnum]--;
+ if (unitsem_cnt[unitnum] < 0)
+ write_log (L"CD: unitsem%d release mismatch! cnt=%d\n", unitnum, unitsem_cnt[unitnum]);
+ uae_sem_post (&unitsem[unitnum]);
+}
+static void sys_command_close_internal (int unitnum)
+{
+ getsem (unitnum, true);
+ waspaused[unitnum] = 0;
+ if (openlist[unitnum] <= 0)
+ write_log (L"BUG unit %d close: opencnt=%d!\n", unitnum, openlist[unitnum]);
+ if (device_func[unitnum]) {
+ device_func[unitnum]->closedev (unitnum);
+ if (openlist[unitnum] > 0)
+ openlist[unitnum]--;
+ }
+ freesem (unitnum);
+ if (openlist[unitnum] == 0) {
+ uae_sem_destroy (&unitsem[unitnum]);
+ unitsem[unitnum] = NULL;
+ }
+}
+
static int sys_command_open_internal (int unitnum, const TCHAR *ident, cd_standard_unit csu)
{
int ret = 0;
+ if (unitsem[unitnum] == NULL)
+ uae_sem_init (&unitsem[unitnum], 0, 1);
+ getsem (unitnum, true);
if (openlist[unitnum])
write_log (L"BUG unit %d open: opencnt=%d!\n", unitnum, openlist[unitnum]);
if (device_func[unitnum]) {
if (ret)
openlist[unitnum]++;
}
+ freesem (unitnum);
return ret;
}
return sys_command_open_internal (unitnum, currprefs.cdslots[unitnum].name[0] ? currprefs.cdslots[unitnum].name : NULL, CD_STANDARD_UNIT_DEFAULT);
}
-
void sys_command_close (int unitnum)
{
- waspaused[unitnum] = 0;
- if (openlist[unitnum] <= 0)
- write_log (L"BUG unit %d close: opencnt=%d!\n", unitnum, openlist[unitnum]);
- if (device_func[unitnum]) {
- device_func[unitnum]->closedev (unitnum);
- if (openlist[unitnum] > 0)
- openlist[unitnum]--;
- }
+ sys_command_close_internal (unitnum);
}
void blkdev_cd_change (int unitnum, const TCHAR *name)
changed = true;
if (changed) {
+ if (unitsem[unitnum])
+ getsem (unitnum, true);
cdimagefileinuse[unitnum] = changed_prefs.cdslots[unitnum].inuse;
_tcscpy (newimagefiles[unitnum], changed_prefs.cdslots[unitnum].name);
changed_prefs.cdslots[unitnum].name[0] = currprefs.cdslots[unitnum].name[0] = 0;
#ifdef RETROPLATFORM
rp_cd_image_change (unitnum, NULL);
#endif
+ if (unitsem[unitnum])
+ freesem (unitnum);
}
if (imagechangetime[unitnum] == 0)
return;
imagechangetime[unitnum]--;
if (imagechangetime[unitnum] > 0)
return;
+ if (unitsem[unitnum])
+ getsem (unitnum, true);
_tcscpy (currprefs.cdslots[unitnum].name, newimagefiles[unitnum]);
_tcscpy (changed_prefs.cdslots[unitnum].name, newimagefiles[unitnum]);
currprefs.cdslots[unitnum].inuse = changed_prefs.cdslots[unitnum].inuse = cdimagefileinuse[unitnum];
#ifdef RETROPLATFORM
rp_cd_image_change (unitnum, currprefs.cdslots[unitnum].name);
#endif
+ if (unitsem[unitnum])
+ freesem (unitnum);
+
config_changed = 1;
}
static int audiostatus (int unitnum)
{
+ if (!getsem (unitnum))
+ return 0;
uae_u8 cmd[10] = {0x42,2,0x40,1,0,0,0,(uae_u8)(DEVICE_SCSI_BUFSIZE>>8),(uae_u8)(DEVICE_SCSI_BUFSIZE&0xff),0};
uae_u8 *p = device_func[unitnum]->exec_in (unitnum, cmd, sizeof (cmd), 0);
+ freesem (unitnum);
if (!p)
return 0;
return p[1];
{
if (failunit (unitnum))
return -1;
+ if (!getsem (unitnum))
+ return 0;
+ int v;
if (device_func[unitnum]->pause == NULL) {
int as = audiostatus (unitnum);
uae_u8 cmd[10] = {0x4b,0,0,0,0,0,0,0,paused?0:1,0};
do_scsi (unitnum, cmd, sizeof cmd);
- return as == AUDIO_STATUS_PAUSED;
+ v = as == AUDIO_STATUS_PAUSED;
+ } else {
+ v = device_func[unitnum]->pause (unitnum, paused);
}
- return device_func[unitnum]->pause (unitnum, paused);
+ freesem (unitnum);
+ return v;
}
/* stop CD audio */
{
if (failunit (unitnum))
return;
+ if (!getsem (unitnum))
+ return;
if (device_func[unitnum]->stop == NULL) {
int as = audiostatus (unitnum);
uae_u8 cmd[6] = {0x4e,0,0,0,0,0};
do_scsi (unitnum, cmd, sizeof cmd);
- return;
- }
- device_func[unitnum]->stop (unitnum);
-}
-
-#if 0
-static int adjustplaypos (int unitnum, int startlsn)
-{
- uae_u8 q[SUBQ_SIZE];
- if (!device_func[unitnum]->qcode (unitnum, q, startlsn - 1))
- return startlsn;
- int otrack = frombcd (q[4 + 1]);
- int lsn = startlsn;
- int max = 150;
- while (max-- > 0 && startlsn > 0) {
- if (!device_func[unitnum]->qcode (unitnum, q, startlsn - 1))
- break;
- int track = frombcd (q[4 + 1]);
- int idx = frombcd (q[4 + 2]);
- //write_log (L"%d %d\n", track, idx);
- if (idx != 0 || otrack != track)
- break;
- startlsn--;
+ } else {
+ device_func[unitnum]->stop (unitnum);
}
- if (lsn != startlsn)
- write_log (L"CD play adjust %d -> %d\n", lsn, startlsn);
- startlsn -= 10;
- if (startlsn < 0)
- startlsn = 0;
- return startlsn;
+ freesem (unitnum);
}
-#endif
/* play CD audio */
int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan)
{
+ int v;
if (failunit (unitnum))
return 0;
+ if (!getsem (unitnum))
+ return 0;
if (device_func[unitnum]->play == NULL) {
uae_u8 cmd[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
int startmsf = lsn2msf (startlsn);
cmd[6] = (uae_u8)(endmsf >> 16);
cmd[7] = (uae_u8)(endmsf >> 8);
cmd[8] = (uae_u8)(endmsf >> 0);
- return do_scsi (unitnum, cmd, sizeof cmd) ? 0 : 1;
+ v = do_scsi (unitnum, cmd, sizeof cmd) ? 0 : 1;
+ } else {
+ v = device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, NULL, NULL);
}
- //startlsn = adjustplaypos (unitnum, startlsn);
- return device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, NULL, NULL);
+ freesem (unitnum);
+ return v;
}
/* play CD audio with subchannels */
int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan, play_status_callback statusfunc, play_subchannel_callback subfunc)
{
+ int v;
if (failunit (unitnum))
return 0;
+ if (!getsem (unitnum))
+ return 0;
if (device_func[unitnum]->play == NULL)
- return sys_command_cd_play (unitnum, startlsn, endlsn, scan);
- //startlsn = adjustplaypos (unitnum, startlsn);
- return device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, statusfunc, subfunc);
+ v = sys_command_cd_play (unitnum, startlsn, endlsn, scan);
+ else
+ v = device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, statusfunc, subfunc);
+ freesem (unitnum);
+ return v;
}
/* set CD audio volume */
uae_u32 sys_command_cd_volume (int unitnum, uae_u16 volume_left, uae_u16 volume_right)
{
+ int v;
if (failunit (unitnum))
return 0;
+ if (!getsem (unitnum))
+ return 0;
if (device_func[unitnum]->volume == NULL)
- return -1;
- return device_func[unitnum]->volume (unitnum, volume_left, volume_right);
+ v = -1;
+ else
+ v = device_func[unitnum]->volume (unitnum, volume_left, volume_right);
+ freesem (unitnum);
+ return v;
}
/* read qcode */
int sys_command_cd_qcode (int unitnum, uae_u8 *buf)
{
+ int v;
if (failunit (unitnum))
return 0;
+ if (!getsem (unitnum))
+ return 0;
if (device_func[unitnum]->qcode == NULL) {
uae_u8 cmd[10] = {0x42,2,0x40,1,0,0,0,(uae_u8)(SUBQ_SIZE>>8),(uae_u8)(SUBQ_SIZE&0xff),0};
- return do_scsi (unitnum, cmd, sizeof cmd, buf, SUBQ_SIZE);
+ v = do_scsi (unitnum, cmd, sizeof cmd, buf, SUBQ_SIZE);
+ } else {
+ v = device_func[unitnum]->qcode (unitnum, buf, -1);
}
- return device_func[unitnum]->qcode (unitnum, buf, -1);
+ freesem (unitnum);
+ return v;
};
/* read table of contents */
int sys_command_cd_toc (int unitnum, struct cd_toc_head *toc)
{
+ int v;
if (failunit (unitnum))
return 0;
+ if (!getsem (unitnum))
+ return 0;
if (device_func[unitnum]->toc == NULL) {
uae_u8 buf[4 + 8 * 103];
int size = sizeof buf;
uae_u8 cmd [10] = { 0x43,0,2,0,0,0,0,(uae_u8)(size>>8),(uae_u8)(size&0xff),0};
if (do_scsi (unitnum, cmd, sizeof cmd, buf, size)) {
// toc parse to do
- return 0;
+ v = 0;
}
- return 0;
+ v = 0;
+ } else {
+ v = device_func[unitnum]->toc (unitnum, toc);
}
- return device_func[unitnum]->toc (unitnum, toc);
+ freesem (unitnum);
+ return v;
}
/* read one cd sector */
int sys_command_cd_read (int unitnum, uae_u8 *data, int block, int size)
{
+ int v;
if (failunit (unitnum))
return 0;
+ if (!getsem (unitnum))
+ return 0;
if (device_func[unitnum]->read == NULL) {
uae_u8 cmd[12] = { 0xbe, 0, block >> 24, block >> 16, block >> 8, block >> 0, size >> 16, size >> 8, size >> 0, 0x10, 0, 0 };
cmd[1] = 2 << 3; // 2048
if (!do_scsi (unitnum, cmd, sizeof cmd, data, size * 2048))
cmd[1] = 4 << 3; // 2048 mode2
- return do_scsi (unitnum, cmd, sizeof cmd, data, size * 2048);
+ v = do_scsi (unitnum, cmd, sizeof cmd, data, size * 2048);
+ } else {
+ v = device_func[unitnum]->read (unitnum, data, block, size);
}
- return device_func[unitnum]->read (unitnum, data, block, size);
+ freesem (unitnum);
+ return v;
}
int sys_command_cd_rawread (int unitnum, uae_u8 *data, int block, int size, int sectorsize)
{
+ int v;
if (failunit (unitnum))
return -1;
+ if (!getsem (unitnum))
+ return 0;
if (device_func[unitnum]->rawread == NULL) {
uae_u8 cmd[12] = { 0xbe, 0, block >> 24, block >> 16, block >> 8, block >> 0, size >> 16, size >> 8, size >> 0, 0x10, 0, 0 };
- return do_scsi (unitnum, cmd, sizeof cmd, data, size * sectorsize);
+ v = do_scsi (unitnum, cmd, sizeof cmd, data, size * sectorsize);
+ } else {
+ v = device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, 0xffffffff);
}
- return device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, 0xffffffff);
+ freesem (unitnum);
+ return v;
}
int sys_command_cd_rawread (int unitnum, uae_u8 *data, int block, int size, int sectorsize, uae_u8 sectortype, uae_u8 scsicmd9, uae_u8 subs)
{
+ int v;
if (failunit (unitnum))
return -1;
+ if (!getsem (unitnum))
+ return 0;
if (device_func[unitnum]->rawread == NULL) {
uae_u8 cmd[12] = { 0xbe, 0, block >> 24, block >> 16, block >> 8, block >> 0, size >> 16, size >> 8, size >> 0, 0x10, 0, 0 };
- return do_scsi (unitnum, cmd, sizeof cmd, data, size * sectorsize);
+ v = do_scsi (unitnum, cmd, sizeof cmd, data, size * sectorsize);
+ } else {
+ v = device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, (sectortype << 16) | (scsicmd9 << 8) | subs);
}
- return device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, (sectortype << 16) | (scsicmd9 << 8) | subs);
+ freesem (unitnum);
+ return v;
}
/* read block */
int sys_command_read (int unitnum, uae_u8 *data, int block, int size)
{
+ int v;
if (failunit (unitnum))
return 0;
+ if (!getsem (unitnum))
+ return 0;
if (device_func[unitnum]->read == NULL) {
uae_u8 cmd[12] = { 0xa8, 0, 0, 0, 0, 0, size >> 24, size >> 16, size >> 8, size >> 0, 0, 0 };
cmd[2] = (uae_u8)(block >> 24);
cmd[3] = (uae_u8)(block >> 16);
cmd[4] = (uae_u8)(block >> 8);
cmd[5] = (uae_u8)(block >> 0);
- return do_scsi (unitnum, cmd, sizeof cmd, data, size * 2048);
+ v = do_scsi (unitnum, cmd, sizeof cmd, data, size * 2048);
+ } else {
+ v = device_func[unitnum]->read (unitnum, data, block, size);
}
- return device_func[unitnum]->read (unitnum, data, block, size);
+ freesem (unitnum);
+ return v;
}
/* write block */
int sys_command_write (int unitnum, uae_u8 *data, int offset, int size)
{
+ int v;
if (failunit (unitnum))
return 0;
- if (device_func[unitnum]->write == NULL)
+ if (!getsem (unitnum))
return 0;
- return device_func[unitnum]->write (unitnum, data, offset, size);
+ if (device_func[unitnum]->write == NULL) {
+ v = 0;
+ } else {
+ v = device_func[unitnum]->write (unitnum, data, offset, size);
+ }
+ freesem (unitnum);
+ return v;
}
int sys_command_ismedia (int unitnum, int quick)
{
+ int v;
if (failunit (unitnum))
return -1;
if (delayed[unitnum])
return 0;
+ if (!getsem (unitnum))
+ return 0;
if (device_func[unitnum] == NULL) {
uae_u8 cmd[6] = { 0, 0, 0, 0, 0, 0 };
- return do_scsi (unitnum, cmd, sizeof cmd);
+ v = do_scsi (unitnum, cmd, sizeof cmd);
} else {
- return device_func[unitnum]->ismedia (unitnum, quick);
+ v = device_func[unitnum]->ismedia (unitnum, quick);
}
+ freesem (unitnum);
+ return v;
}
struct device_info *sys_command_info (int unitnum, struct device_info *di, int quick)
{
if (failunit (unitnum))
return NULL;
+ if (!getsem (unitnum))
+ return 0;
struct device_info *di2 = device_func[unitnum]->info (unitnum, di, quick);
if (di2 && delayed[unitnum])
di2->media_inserted = 0;
+ freesem (unitnum);
return di2;
}
}
static uae_u64 cmd_readx (int unitnum, uae_u8 *dataptr, int offset, int len)
{
- if (device_func[unitnum]->read (unitnum, dataptr, offset, len))
- return len;
- else
+ if (!getsem (unitnum))
return 0;
+ int v = device_func[unitnum]->read (unitnum, dataptr, offset, len);
+ freesem (unitnum);
+ if (v)
+ return len;
+ return 0;
}
static void wl (uae_u8 *p, int v)
scsi_len = 0;
goto end;
}
- write_log (L"SCSIEMU %d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X CMDLEN=%d DATA=%08X LEN=%d\n", unitnum,
- cmdbuf[0], cmdbuf[1], cmdbuf[2], cmdbuf[3], cmdbuf[4], cmdbuf[5], cmdbuf[6],
- cmdbuf[7], cmdbuf[8], cmdbuf[9], cmdbuf[10], cmdbuf[11],
- scsi_cmd_len, scsi_data, *data_len);
+ if (log_scsiemu)
+ write_log (L"SCSIEMU %d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X CMDLEN=%d DATA=%08X LEN=%d\n", unitnum,
+ cmdbuf[0], cmdbuf[1], cmdbuf[2], cmdbuf[3], cmdbuf[4], cmdbuf[5], cmdbuf[6],
+ cmdbuf[7], cmdbuf[8], cmdbuf[9], cmdbuf[10], cmdbuf[11],
+ scsi_cmd_len, scsi_data, *data_len);
switch (cmdbuf[0])
{
case 0x12: /* INQUIRY */
int dbd = cmdbuf[1] & 8;
if (cmdbuf[0] == 0x5a)
dbd = 1;
- write_log (L"MODE SENSE PC=%d CODE=%d DBD=%d\n", pc, pcode, dbd);
+ if (log_scsiemu)
+ write_log (L"MODE SENSE PC=%d CODE=%d DBD=%d\n", pc, pcode, dbd);
p = r;
if (cmdbuf[0] == 0x5a) {
p[0] = 8 - 1;
*data_len = scsi_len;
*reply_len = lr;
*sense_len = ls;
- if (cmdbuf[0])
+ if (cmdbuf[0] && log_scsiemu)
write_log (L"-> DATAOUT=%d ST=%d SENSELEN=%d\n", scsi_len, status, ls);
return status;
}
as->cmdactual = as->status != 0 ? 0 : as->cmd_len; /* fake scsi_CmdActual */
if (as->status) {
- io_error = 45; /* HFERR_BadStatus */
+ io_error = IOERR_BadStatus;
as->sense_len = senselen;
as->actual = 0; /* scsi_Actual */
} else {
as->sensedata[i] = 0;
sactual = 0;
if (datalen < 0) {
- io_error = 20; /* io_Error, but not specified */
+ io_error = IOERR_NotSpecified;
as->actual = 0; /* scsi_Actual */
} else {
as->len = datalen;
bank = &get_mem_bank (ap);
if (!bank || !bank->check(ap, as.len))
- return -5;
+ return IOERR_BADADDRESS;
as.data = bank->xlateaddr (ap);
ap = get_long (acmd + 12);
as.cmd_len = get_word (acmd + 16);
+ if (as.cmd_len > sizeof as.cmd)
+ return IOERR_BADLENGTH;
for (i = 0; i < as.cmd_len; i++)
as.cmd[i] = get_byte (ap++);
while (i < sizeof as.cmd)
int cdda_start, cdda_end;
play_subchannel_callback cdda_subfunc;
play_status_callback cdda_statusfunc;
- int cdda_delay;
+ int cdda_delay, cdda_delay_frames;
int imagechange;
TCHAR newfile[MAX_DPATH];
return NULL;
}
+
static struct cdtoc *findtoc (struct cdunit *cdu, int *sectorp)
{
int i;
int sector;
+ if (*sectorp < 0)
+ return NULL;
sector = *sectorp;
for (i = 0; i <= cdu->tracks; i++) {
struct cdtoc *t = &cdu->toc[i];
}
}
-static int getsub (uae_u8 *dst, struct cdunit *cdu, struct cdtoc *t, int sector)
+static int getsub_deinterleaved (uae_u8 *dst, struct cdunit *cdu, struct cdtoc *t, int sector)
{
int ret = 0;
uae_sem_wait (&cdu->sub_sem);
return ret;
}
-static void dosub (struct cdunit *cdu, struct cdtoc *t, int sector)
+static void dosub (struct cdunit *cdu, uae_u8 *subbuf)
{
- uae_u8 *d;
- uae_u8 subbuf[SUB_CHANNEL_SIZE];
uae_u8 subbuf2[SUB_CHANNEL_SIZE];
if (!cdu->cdda_subfunc)
return;
- if (!t) {
- memset (subbuf, 0, sizeof subbuf);
- cdu->cdda_subfunc (subbuf, 1);
+ if (!subbuf) {
+ memset (subbuf2, 0, sizeof subbuf2);
+ cdu->cdda_subfunc (subbuf2, 1);
return;
}
- memset (subbuf, 0, SUB_CHANNEL_SIZE);
- int mode = getsub (subbuf, cdu, t, sector);
- if (mode == 2) { // deinterleaved -> interleaved
- sub_to_interleaved (subbuf, subbuf2);
- d = subbuf2;
- } else {
- d = subbuf;
- }
- cdu->cdda_subfunc (d, 1);
+ sub_to_interleaved (subbuf, subbuf2);
+ cdu->cdda_subfunc (subbuf2, 1);
}
static int setstate (struct cdunit *cdu, int state)
MMRESULT mmr;
int volume[2], volume_main;
int oldplay;
+ int idleframes;
+ bool foundsub;
struct cdunit *cdu = (struct cdunit*)v;
for (i = 0; i < 2; i++) {
int sector, diff;
struct _timeb tb1, tb2;
+ idleframes = 0;
+ foundsub = false;
_ftime (&tb1);
cdda_pos = cdu->cdda_start;
oldplay = cdu->cdda_play;
- cdu->cd_last_pos = cdda_pos;
- sector = cdu->cdda_start;
+ sector = cdu->cd_last_pos = cdda_pos;
t = findtoc (cdu, §or);
if (!t) {
write_log (L"IMAGE CDDA: illegal sector number %d\n", cdu->cdda_start);
while (cdimage_unpack_active == 0)
Sleep (10);
}
+ idleframes = cdu->cdda_delay_frames;
+ while (cdu->cdda_paused && cdu->cdda_play > 0) {
+ Sleep (10);
+ idleframes = -1;
+ }
+
+ if (cdu->cdda_scan == 0) {
+ // find possible P-subchannel=1 and fudge starting point so that
+ // buggy CD32/CDTV software CD+G handling does not miss any frames
+ bool seenindex = false;
+ for (sector = cdda_pos - 200; sector < cdda_pos; sector++) {
+ int sec = sector;
+ t = findtoc (cdu, &sec);
+ if (t) {
+ uae_u8 subbuf[SUB_CHANNEL_SIZE];
+ getsub_deinterleaved (subbuf, cdu, t, sector);
+ if (seenindex) {
+ for (int i = 2 * SUB_ENTRY_SIZE; i < SUB_CHANNEL_SIZE; i++) {
+ if (subbuf[i]) { // non-zero R-W subchannels
+ int diff = cdda_pos - sector + 2;
+ write_log (L"-> CD+G start pos fudge -> %d (%d)\n", sector, -diff);
+ idleframes -= diff;
+ cdda_pos = sector;
+ break;
+ }
+ }
+ } else if (subbuf[0] == 0xff) { // P == 1?
+ seenindex = true;
+ }
+ }
+ }
+ }
+ cdda_pos -= idleframes;
+
_ftime (&tb2);
diff = (tb2.time * (uae_s64)1000 + tb2.millitm) - (tb1.time * (uae_s64)1000 + tb1.millitm);
diff -= cdu->cdda_delay;
- if (diff < 0 && cdu->cdda_play > 0)
+ if (idleframes >= 0 && diff < 0 && cdu->cdda_play > 0)
Sleep (-diff);
setstate (cdu, AUDIO_STATUS_IN_PROGRESS);
}
}
bufon[bufnum] = 0;
- if (!isaudiotrack (&cdu->di.toc, cdda_pos)) {
+ if (idleframes <= 0 && !isaudiotrack (&cdu->di.toc, cdda_pos)) {
setstate (cdu, AUDIO_STATUS_PLAY_ERROR);
goto end; // data track?
}
memset (px[bufnum], 0, num_sectors * 2352);
for (cnt = 0; cnt < num_sectors; cnt++) {
+ uae_u8 *dst = px[bufnum] + cnt * 2352;
+ uae_u8 subbuf[SUB_CHANNEL_SIZE];
sector = cdda_pos;
- if (cdu->cdda_scan) {
- cdda_pos += cdu->cdda_scan;
- if (cdda_pos < 0)
- cdda_pos = 0;
- } else {
- cdda_pos++;
- }
- if (cdda_pos - num_sectors < cdu->cdda_end && cdda_pos >= cdu->cdda_end)
- dofinish = 1;
+ memset (subbuf, 0, SUB_CHANNEL_SIZE);
t = findtoc (cdu, §or);
if (t) {
if (t->handle && !(t->ctrl & 4)) {
- uae_u8 *dst = px[bufnum] + cnt * t->size;
int totalsize = t->size + t->skipsize;
if ((t->enctype == AUDENC_MP3 || t->enctype == AUDENC_FLAC) && t->data) {
if (t->filesize >= sector * totalsize + t->offset + t->size)
}
}
}
- dosub (cdu, t, cdda_pos);
+ getsub_deinterleaved (subbuf, cdu, t, cdda_pos);
+ }
+
+ if (idleframes > 0) {
+ idleframes--;
+ memset (dst, 0, 2352);
+ memset (subbuf, 0, SUB_CHANNEL_SIZE);
+ }
+
+ if (cdda_pos < cdu->cdda_start && cdu->cdda_scan == 0)
+ memset (dst, 0, 2352);
+
+ dosub (cdu, subbuf);
+
+ if (cdu->cdda_scan) {
+ cdda_pos += cdu->cdda_scan;
+ if (cdda_pos < 0)
+ cdda_pos = 0;
+ } else {
+ cdda_pos++;
}
+
+ if (cdda_pos - num_sectors < cdu->cdda_end && cdda_pos >= cdu->cdda_end)
+ dofinish = 1;
+
}
+ if (idleframes <= 0)
+ cdu->cd_last_pos = cdda_pos;
+
volume_main = currprefs.sound_volume;
int vol_mult[2];
for (int j = 0; j < 2; j++) {
break;
}
- cdu->cd_last_pos = cdda_pos;
-
if (dofinish) {
setstate (cdu, AUDIO_STATUS_PLAY_COMPLETE);
cdu->cdda_play = -1;
}
}
cdu->cdda_paused = 0;
+ cdu->cdda_play_state = 0;
}
cdu->cdda_statusfunc = statusfunc;
cdu->cdda_scan = scan > 0 ? 10 : (scan < 0 ? 10 : 0);
cdu->cdda_delay = setstate (cdu, -1);
+ cdu->cdda_delay_frames = setstate (cdu, -2);
setstate (cdu, AUDIO_STATUS_NOT_SUPPORTED);
if (!isaudiotrack (&cdu->di.toc, startlsn)) {
setstate (cdu, AUDIO_STATUS_PLAY_ERROR);
}
if (!td)
return 0;
- getsub (subbuf, cdu, td, pos);
+ getsub_deinterleaved (subbuf, cdu, td, pos);
memcpy (p, subbuf + 12, 12);
// write_log (L"%6d %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x\n",
// pos, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11]);
struct cdtoc *t = findtoc (cdu, §or);
if (!t || t->handle == NULL)
- return 0;
+ goto end;
+
cdda_stop (cdu);
if (sectorsize > 0) {
if (sectorsize == 2352 && t->size == 2048) {
int edcecc = (cmd9 >> 3) & 1;
int errorfield = (cmd9 >> 1) & 3;
uae_u8 subs = extra & 7;
- if (subs != 0 && subs != 1 && subs != 2 && subs != 4)
- return -1;
+ if (subs != 0 && subs != 1 && subs != 2 && subs != 4) {
+ ret = -1;
+ goto end;
+ }
if (isaudiotrack (&cdu->di.toc, sector)) {
- if (sectortype != 0 && sectortype != 1)
- return -2;
- if (t->size != 2352)
- return -1;
+ if (sectortype != 0 && sectortype != 1) {
+ ret = -2;
+ goto end;
+ }
+ if (t->size != 2352) {
+ ret = -1;
+ goto end;
+ }
for (int i = 0; i < size; i++) {
zfile_fseek (t->handle, t->offset + sector * t->size, SEEK_SET);
zfile_fread (data, t->size, 1, t->handle);
uae_u8 *p = data + t->size;
if (subs) {
uae_u8 subdata[SUB_CHANNEL_SIZE];
- getsub (subdata, cdu, t, sector);
+ getsub_deinterleaved (subdata, cdu, t, sector);
if (subs == 4) { // all, de-interleaved
memcpy (p, subdata, SUB_CHANNEL_SIZE);
p += SUB_CHANNEL_SIZE;
}
}
}
+end:
return ret;
}
struct cdtoc *t = findtoc (cdu, §or);
if (!t || t->handle == NULL)
- return NULL;
+ return 0;
cdda_stop (cdu);
if (t->size == 2048) {
zfile_fseek (t->handle, t->offset + sector * t->size, SEEK_SET);
return 1;
}
-
static int ismedia (int unitnum, int quick)
{
struct cdunit *cdu = &cdunits[unitnum];
static int open_device (int unitnum, const TCHAR *ident, int flags)
{
struct cdunit *cdu = &cdunits[unitnum];
+ int ret = 0;
- if (cdu->open)
- return 0;
- uae_sem_init (&cdu->sub_sem, 0, 1);
- parse_image (cdu, ident);
- cdu->open = true;
- cdu->enabled = true;
- cdu->cdda_volume[0] = 0x7fff;
- cdu->cdda_volume[1] = 0x7fff;
- blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name);
- if (cdimage_unpack_thread == 0) {
- init_comm_pipe (&unpack_pipe, 10, 1);
- uae_start_thread (L"cdimage_unpack", cdda_unpack_func, NULL, NULL);
- while (cdimage_unpack_thread == 0)
- Sleep (10);
+ if (!cdu->open) {
+ uae_sem_init (&cdu->sub_sem, 0, 1);
+ parse_image (cdu, ident);
+ cdu->open = true;
+ cdu->enabled = true;
+ cdu->cdda_volume[0] = 0x7fff;
+ cdu->cdda_volume[1] = 0x7fff;
+ if (cdimage_unpack_thread == 0) {
+ init_comm_pipe (&unpack_pipe, 10, 1);
+ uae_start_thread (L"cdimage_unpack", cdda_unpack_func, NULL, NULL);
+ while (cdimage_unpack_thread == 0)
+ Sleep (10);
+ }
+ ret = 1;
}
- return 1;
+ blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name);
+ return ret;
}
static void close_device (int unitnum)
{
struct cdunit *cdu = &cdunits[unitnum];
- if (cdu->open == false)
- return;
- cdda_stop (cdu);
- unload_image (cdu);
- uae_sem_destroy (&cdu->sub_sem);
- cdu->open = false;
- blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name);
- if (cdimage_unpack_thread) {
- cdimage_unpack_thread = 0;
- write_comm_pipe_u32 (&unpack_pipe, -1, 0);
- write_comm_pipe_u32 (&unpack_pipe, -1, 1);
- while (cdimage_unpack_thread == 0)
- Sleep (10);
- cdimage_unpack_thread = 0;
- destroy_comm_pipe (&unpack_pipe);
+ if (cdu->open) {
+ cdda_stop (cdu);
+ unload_image (cdu);
+ uae_sem_destroy (&cdu->sub_sem);
+ cdu->open = false;
+ if (cdimage_unpack_thread) {
+ cdimage_unpack_thread = 0;
+ write_comm_pipe_u32 (&unpack_pipe, -1, 0);
+ write_comm_pipe_u32 (&unpack_pipe, -1, 1);
+ while (cdimage_unpack_thread == 0)
+ Sleep (10);
+ cdimage_unpack_thread = 0;
+ destroy_comm_pipe (&unpack_pipe);
+ }
}
+ blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name);
}
static void close_bus (void)
}
static int statusfunc (int status)
{
- if (status < 0)
+ if (status == -1)
return 500;
+ if (status == -2)
+ return 75;
if (cd_audio_status != status) {
if (status == AUDIO_STATUS_PLAY_COMPLETE || status == AUDIO_STATUS_PLAY_ERROR) {
cd_audio_finished = 1;
if (cdrom_command_cnt_in == 7) {
cdrom_command_accepted (0, s, &cdrom_command_cnt_in);
cd_finished = 1;
+ sleep_millis (500);
+ activate_stch = 1;
}
break;
case 0x02: /* read */
*next2++ = 0;
cfgfile_intval (option, next, tmp, &unitnum, 1);
}
- _tcsncpy (p->cdslots[i].name, value, sizeof p->cdslots[i].name / sizeof (TCHAR));
+ if (_tcslen (value) > 0)
+ _tcsncpy (p->cdslots[i].name, value, sizeof p->cdslots[i].name / sizeof (TCHAR));
p->cdslots[i].name[sizeof p->cdslots[i].name - 1] = 0;
p->cdslots[i].inuse = true;
p->cdslots[i].type = type;
return 0;
}
-static void decode_rom_ident (TCHAR *romfile, int maxlen, TCHAR *ident)
+static void decode_rom_ident (TCHAR *romfile, int maxlen, const TCHAR *ident, int romflags)
{
- TCHAR *p;
+ const TCHAR *p;
int ver, rev, subver, subrev, round, i;
TCHAR model[64], *modelp;
struct romlist **rl;
while (*p) {
TCHAR c = *p++;
int *pp1 = NULL, *pp2 = NULL;
- if (_totupper(c) == 'V' && _istdigit(*p)) {
+ if (_totupper (c) == 'V' && _istdigit (*p)) {
pp1 = &ver;
pp2 = &rev;
- } else if (_totupper(c) == 'R' && _istdigit(*p)) {
+ } else if (_totupper (c) == 'R' && _istdigit (*p)) {
pp1 = &subver;
pp2 = &subrev;
- } else if (!_istdigit(c) && c != ' ') {
- _tcsncpy (model, p - 1, (sizeof model) - 1);
+ } else if (!_istdigit (c) && c != ' ') {
+ _tcsncpy (model, p - 1, (sizeof model) / sizeof (TCHAR) - 1);
p += _tcslen (model);
modelp = model;
}
if (pp1) {
- *pp1 = _tstol(p);
+ *pp1 = _tstol (p);
while (*p != 0 && *p != '.' && *p != ' ')
p++;
if (*p == '.') {
p++;
if (pp2)
- *pp2 = _tstol(p);
+ *pp2 = _tstol (p);
}
}
if (*p == 0 || *p == ';') {
- rl = getromlistbyident (ver, rev, subver, subrev, modelp, round);
+ rl = getromlistbyident (ver, rev, subver, subrev, modelp, romflags, round > 0);
if (rl) {
for (i = 0; rl[i]; i++) {
if (round) {
p->custom_memory_sizes[num] = size;
}
-static int cfgfile_parse_hardware (struct uae_prefs *p, TCHAR *option, TCHAR *value)
+static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCHAR *value)
{
int tmpval, dummyint, i;
bool tmpbool, dummybool;
return 1;
}
if (cfgfile_string (option, value, L"kickstart_rom", p->romident, sizeof p->romident / sizeof (TCHAR))) {
- decode_rom_ident (p->romfile, sizeof p->romfile / sizeof (TCHAR), p->romident);
+ decode_rom_ident (p->romfile, sizeof p->romfile / sizeof (TCHAR), p->romident, ROMTYPE_ALL_KICK);
return 1;
}
if (cfgfile_string (option, value, L"kickstart_ext_rom", p->romextident, sizeof p->romextident / sizeof (TCHAR))) {
- decode_rom_ident (p->romextfile, sizeof p->romextfile / sizeof (TCHAR), p->romextident);
+ decode_rom_ident (p->romextfile, sizeof p->romextfile / sizeof (TCHAR), p->romextident, ROMTYPE_ALL_EXT);
return 1;
}
if (cfgfile_string (option, value, L"cart", p->cartident, sizeof p->cartident / sizeof (TCHAR))) {
- decode_rom_ident (p->cartfile, sizeof p->cartfile / sizeof (TCHAR), p->cartident);
+ decode_rom_ident (p->cartfile, sizeof p->cartfile / sizeof (TCHAR), p->cartident, ROMTYPE_ALL_CART);
return 1;
}
action_replay_ciaread ();
#endif
tmp = DISK_status() & 0x3c;
- tmp |= handle_joystick_buttons (ciaadra);
+ tmp |= handle_joystick_buttons (ciaapra, ciaadra);
tmp |= (ciaapra | (ciaadra ^ 3)) & 0x03;
- if (ciaadra & 0x40)
- tmp = (tmp & ~0x40) | (ciaapra & 0x40);
- if (ciaadra & 0x80)
- tmp = (tmp & ~0x80) | (ciaapra & 0x80);
tmp = dongle_cia_read (0, reg, tmp);
#if DONGLE_DEBUG > 0
if (notinrom())
int canauto;
const TCHAR *ext;
- gui_disk_image_change (dnum, fname);
drive_image_free (drv);
DISK_validate_filename (fname, 1, &drv->wrprot, &drv->crc32, &drv->diskfile);
drv->ddhd = 1;
drv->useturbo = 0;
drv->indexoffset = 0;
+ gui_disk_image_change (dnum, fname, drv->wrprot);
+
canauto = 0;
ext = _tcsrchr (fname, '.');
if (ext) {
#ifdef DRIVESOUND
driveclick_insert (drv - floppy, 1);
#endif
- gui_disk_image_change (drv - floppy, NULL);
+ gui_disk_image_change (drv - floppy, NULL, drv->wrprot);
drive_image_free (drv);
drv->dskchange = 1;
drv->ddhd = 1;
return diskfile_iswriteprotect (name, &needwritefile, &drvtype);
}
-static void diskfile_readonly (const TCHAR *name, int readonly)
+static void diskfile_readonly (const TCHAR *name, bool readonly)
{
struct _stat64 st;
int mode, oldmode;
return;
oldmode = mode = st.st_mode;
mode &= ~FILEFLAG_WRITE;
- if (!readonly) mode |= FILEFLAG_WRITE;
+ if (!readonly)
+ mode |= FILEFLAG_WRITE;
if (mode != oldmode)
chmod (name, mode);
}
setdskchangetime (&floppy[num], 20);
}
-int disk_setwriteprotect (int num, const TCHAR *name, int protect)
+int disk_setwriteprotect (int num, const TCHAR *name, bool writeprotected)
{
int needwritefile, oldprotect;
struct zfile *zf1, *zf2;
if (needwritefile && zf2 == 0)
disk_creatediskfile (name2, 1, drvtype, NULL);
zfile_fclose (zf2);
- if (protect && iswritefileempty (name)) {
+ if (writeprotected && iswritefileempty (name)) {
for (i = 0; i < MAX_FLOPPY_DRIVES; i++) {
if (!_tcscmp (name, floppy[i].newname))
drive_eject (&floppy[i]);
}
if (!needwritefile)
- diskfile_readonly (name, protect);
- diskfile_readonly (name2, protect);
+ diskfile_readonly (name, writeprotected);
+ diskfile_readonly (name2, writeprotected);
DISK_reinsert (num);
return 1;
}
break;
}
if (dr == 4) {
- write_log (L"disk %s DMA started, drvmask=%x motormask=%x\n",
- dskdmaen == 3 ? L"write" : L"read", selected ^ 15, motormask);
+ write_log (L"disk %s DMA started, drvmask=%x motormask=%x PC=%08x\n",
+ dskdmaen == 3 ? L"write" : L"read", selected ^ 15, motormask, M68K_GETPC);
noselected = 1;
} else {
if (disk_debug_logging > 0) {
- write_log (L"disk %s DMA started, drvmask=%x track %d mfmpos %d dmaen=%d\n",
+ write_log (L"disk %s DMA started, drvmask=%x track %d mfmpos %d dmaen=%d PC=%08X\n",
dskdmaen == 3 ? L"write" : L"read", selected ^ 15,
- floppy[dr].cyl * 2 + side, floppy[dr].mfmpos, dma_enable);
+ floppy[dr].cyl * 2 + side, floppy[dr].mfmpos, dma_enable, M68K_GETPC);
disk_dma_debugmsg ();
}
}
extern void DISK_hsync (void);
extern void DISK_reset (void);
extern int disk_getwriteprotect (const TCHAR *name);
-extern int disk_setwriteprotect (int num, const TCHAR *name, int protect);
+extern int disk_setwriteprotect (int num, const TCHAR *name, bool writeprotected);
extern void disk_creatediskfile (TCHAR *name, int type, drive_type adftype, TCHAR *disk_name);
extern void dumpdisk (void);
extern int DISK_history_add (const TCHAR *name, int idx, int type, int donotcheck);
#define IOERR_UNITBUSY -6
#define IOERR_SELFTEST -7
-#define CDERR_NotSpecified 20 /* general catchall */
-#define CDERR_NoSecHdr 21 /* couldn't even find a sector */
-#define CDERR_BadSecPreamble 22 /* sector looked wrong */
-#define CDERR_BadSecID 23 /* ditto */
-#define CDERR_BadHdrSum 24 /* header had incorrect checksum */
-#define CDERR_BadSecSum 25 /* data had incorrect checksum */
-#define CDERR_TooFewSecs 26 /* couldn't find enough sectors */
-#define CDERR_BadSecHdr 27 /* another "sector looked wrong" */
-#define CDERR_WriteProt 28 /* can't write to a protected disk */
-#define CDERR_NoDisk 29 /* no disk in the drive */
-#define CDERR_SeekError 30 /* couldn't find track 0 */
-#define CDERR_NoMem 31 /* ran out of memory */
-#define CDERR_BadUnitNum 32 /* asked for a unit > NUMUNITS */
-#define CDERR_BadDriveType 33 /* not a drive cd.device understands */
-#define CDERR_DriveInUse 34 /* someone else allocated the drive */
-#define CDERR_PostReset 35 /* user hit reset; awaiting doom */
-#define CDERR_BadDataType 36 /* data on disk is wrong type */
-#define CDERR_InvalidState 37 /* invalid cmd under current conditions */
-
-#define CDERR_Phase 42 /* illegal or unexpected SCSI phase */
-#define CDERR_NoBoard 50 /* open failed for non-existant board */
+#define IOERR_NotSpecified 20 /* general catchall */
+#define IOERR_NoSecHdr 21 /* couldn't even find a sector */
+#define IOERR_BadSecPreamble 22 /* sector looked wrong */
+#define IOERR_BadSecID 23 /* ditto */
+#define IOERR_BadHdrSum 24 /* header had incorrect checksum */
+#define IOERR_BadSecSum 25 /* data had incorrect checksum */
+#define IOERR_TooFewSecs 26 /* couldn't find enough sectors */
+#define IOERR_BadSecHdr 27 /* another "sector looked wrong" */
+#define IOERR_WriteProt 28 /* can't write to a protected disk */
+#define IOERR_NoDisk 29 /* no disk in the drive */
+#define IOERR_SeekError 30 /* couldn't find track 0 */
+#define IOERR_NoMem 31 /* ran out of memory */
+#define IOERR_BadUnitNum 32 /* asked for a unit > NUMUNITS */
+#define IOERR_BadDriveType 33 /* not a drive cd.device understands */
+#define IOERR_DriveInUse 34 /* someone else allocated the drive */
+#define IOERR_PostReset 35 /* user hit reset; awaiting doom */
+#define IOERR_BadDataType 36 /* data on disk is wrong type */
+#define IOERR_InvalidState 37 /* invalid cmd under current conditions */
+#define IOERR_BadStatus 45
+#define IOERR_Phase 42 /* illegal or unexpected SCSI phase */
+#define IOERR_NoBoard 50 /* open failed for non-existant board */
#define TDERR_DiskChanged 29
extern void gui_lock (void);
extern void gui_unlock (void);
extern void gui_flicker_led (int, int, int);
-extern void gui_disk_image_change (int, const TCHAR *);
+extern void gui_disk_image_change (int, const TCHAR *, bool writeprotected);
extern unsigned int gui_ledstate;
extern void gui_display (int shortcut);
extern void handle_cd32_joystick_cia (uae_u8, uae_u8);
extern uae_u8 handle_parport_joystick (int port, uae_u8 pra, uae_u8 dra);
-extern uae_u8 handle_joystick_buttons (uae_u8);
+extern uae_u8 handle_joystick_buttons (uae_u8, uae_u8);
extern int getbuttonstate (int joy, int button);
extern int getjoystate (int joy);
extern void inputdevice_reset (void);
extern void write_inputdevice_config (struct uae_prefs *p, struct zfile *f);
-extern void read_inputdevice_config (struct uae_prefs *p, TCHAR *option, TCHAR *value);
+extern void read_inputdevice_config (struct uae_prefs *p, const TCHAR *option, TCHAR *value);
extern void reset_inputdevice_config (struct uae_prefs *pr);
extern int inputdevice_joyport_config (struct uae_prefs *p, TCHAR *value, int portnum, int mode, int type);
extern int inputdevice_getjoyportdevice (int port, int val);
#define ROMTYPE_CD32 0x200000
#define ROMTYPE_SCRAMBLED 0x400000
+#define ROMTYPE_ALL_KICK (ROMTYPE_KICK | ROMTYPE_KICKCD32 | ROMTYPE_CD32)
+#define ROMTYPE_ALL_EXT (ROMTYPE_EXTCD32 | ROMTYPE_EXTCDTV)
+#define ROMTYPE_ALL_CART (ROMTYPE_AR | ROMTYPE_HRTMON | ROMTYPE_NORDIC | ROMTYPE_XPOWER | ROMTYPE_CD32CART)
+
struct romheader {
TCHAR *name;
int id;
extern struct romdata *getromdatabyzfile (struct zfile *f);
extern struct romlist **getarcadiaroms (void);
extern struct romdata *getarcadiarombyname (const TCHAR *name);
-extern struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, const TCHAR *model, int all);
+extern struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, const TCHAR *model, int romflags, bool all);
extern void getromname (const struct romdata*, TCHAR*);
extern struct romdata *getromdatabyname (const TCHAR*);
extern struct romlist *getromlistbyids (const int *ids);
#include "rp.h"
#include "dongle.h"
#include "cdtv.h"
+#ifdef RETROPLATFORM
+#include "rp.h"
+#include "cloanto/RetroPlatformIPC.h"
+#endif
extern int bootrom_header, bootrom_items;
}
}
-static int getnum (TCHAR **pp)
+static int getnum (const TCHAR **pp)
{
- TCHAR *p = *pp;
+ const TCHAR *p = *pp;
int v;
if (!_tcsnicmp (p, L"false", 5))
*pp = p;
return v;
}
-static TCHAR *getstring (TCHAR **pp)
+static TCHAR *getstring (const TCHAR **pp)
{
int i;
static TCHAR str[1000];
- TCHAR *p = *pp;
+ const TCHAR *p = *pp;
if (*p == 0)
return 0;
return true;
}
-static struct inputevent *readevent (TCHAR *name, TCHAR **customp)
+static struct inputevent *readevent (const TCHAR *name, TCHAR **customp)
{
int i = 1;
while (events[i].name) {
return &events[0];
}
-void read_inputdevice_config (struct uae_prefs *pr, TCHAR *option, TCHAR *value)
+void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *value)
{
struct uae_input_device *id = 0;
struct inputevent *ie;
int devnum, num, button, joystick, subnum, idnum, keynum;
- TCHAR *p, *p2, *custom;
+ const TCHAR *p;
+ TCHAR *p2, *custom;
option += 6; /* "input." */
p = getstring (&option);
int isbutton = getbuttonstate (joy, i == 0 ? JOYBUTTON_3 : JOYBUTTON_2);
if (cd32_pad_enabled[joy]) {
- if (i == 0) // 3rd button?
- continue;
- if (cd32padmode (p5dir, p5dat))
- continue;
// only red and blue can be read if CD32 pad and only if it is in normal pad mode
isbutton |= getbuttonstate (joy, JOYBUTTON_CD32_BLUE);
+ // CD32 pad 3rd button line (P5) is always floating
+ if (i == 0)
+ isbutton = 0;
+ if (cd32padmode (p5dir, p5dat))
+ continue;
}
dong = dongle_analogjoy (joy, i);
if (!(potgo_value & pdir) && i == 1 && charge == 0)
charge = 2;
}
+ // CD32 pad in 2-button mode: blue button is not floating
+ if (cd32_pad_enabled[joy] && i == 1 && charge == 0)
+ charge = 2;
+
/* official Commodore mouse has pull-up resistors in button lines
* NOTE: 3rd party mice may not have pullups! */
if (dong < 0 && (mouse_pullup && mouse_port[joy] && digital_port[joy][i]) && charge == 0)
}
-uae_u8 handle_joystick_buttons (uae_u8 dra)
+uae_u8 handle_joystick_buttons (uae_u8 pra, uae_u8 dra)
{
uae_u8 but = 0;
int i;
if (cd32_pad_enabled[i]) {
uae_u16 p5dir = 0x0200 << (i * 4);
uae_u16 p5dat = 0x0100 << (i * 4);
- but |= 0x40 << i;
+ but |= mask;
if (!cd32padmode (p5dir, p5dat)) {
- if (getbuttonstate (i, JOYBUTTON_CD32_RED))
+ if (getbuttonstate (i, JOYBUTTON_CD32_RED) || getbuttonstate (i, JOYBUTTON_1))
but &= ~mask;
}
} else {
if (uaerand () & 1)
but |= mask;
}
-
+ if (dra & mask)
+ but = (but & ~mask) | (pra & mask);
}
}
-
if (inputdevice_logging & 4)
write_log (L"BFE001: %02X:%02X %x\n", dra, but, M68K_GETPC);
return but;
if (ie->type & 4) {
int old = joybutton[joy] & (1 << ie->data);
- if (state)
+ if (state) {
joybutton[joy] |= 1 << ie->data;
- else
+#ifdef RETROPLATFORM
+ rp_update_gameport (joy, RP_JOYSTICK_BUTTON1 << ie->data, 1);
+#endif
+ } else {
joybutton[joy] &= ~(1 << ie->data);
+#ifdef RETROPLATFORM
+ rp_update_gameport (joy, RP_JOYSTICK_BUTTON1 << ie->data, 0);
+#endif
+ }
if (ie->data == 0 && old != (joybutton[joy] & (1 << ie->data)) && currprefs.cpu_cycle_exact) {
// emulate contact bounce, 1st button only, others have capacitors
joydir[joy] |= DIR_UP;
if (bot)
joydir[joy] |= DIR_DOWN;
-
+#ifdef RETROPLATFORM
+ rp_update_gameport (joy, RP_JOYSTICK_LEFT, left);
+ rp_update_gameport (joy, RP_JOYSTICK_RIGHT, right);
+ rp_update_gameport (joy, RP_JOYSTICK_DOWN, bot);
+ rp_update_gameport (joy, RP_JOYSTICK_UP, top);
+#endif
}
break;
case 0: /* ->KEY */
rp_input_change (1);
rp_input_change (2);
rp_input_change (3);
+ for (i = 0; i < MAX_JPORTS; i++)
+ rp_update_gameport (i, -1, 0);
#endif
joybutton[0] = joybutton[1] = 0;
return;
}
for (i = 0; i < MAX_INPUT_SUB_EVENT; i++)
- handle_input_event (id->eventid[ID_AXIS_OFFSET + axis][i], state, max, id->flags[ID_AXIS_OFFSET + axis][i]);
+ handle_input_event (id->eventid[ID_AXIS_OFFSET + axis][i], state, max, id->flags[ID_AXIS_OFFSET + axis][i] & ID_FLAG_AUTOFIRE);
id2->states[axis] = state;
}
int getjoystickstate (int joy)
int cdda_volume[2];
int cdda_scan;
int cdda_volume_main;
- uae_u32 cd_last_pos;
+ int cd_last_pos;
HWAVEOUT cdda_wavehandle;
int cdda_start, cdda_end;
uae_u8 subcode[SUB_CHANNEL_SIZE * CDDA_BUFFERS];
play_subchannel_callback cdda_subfunc;
play_status_callback cdda_statusfunc;
int cdda_play_state;
- int cdda_delay;
+ int cdda_delay, cdda_delay_frames;
struct device_info di;
uae_sem_t sub_sem, sub_sem2;
bool open;
return 1;
}
+static void sub_deinterleave (const uae_u8 *s, uae_u8 *d)
+{
+ for (int i = 0; i < 8 * 12; i ++) {
+ int dmask = 0x80;
+ int smask = 1 << (7 - (i / 12));
+ (*d) = 0;
+ for (int j = 0; j < 8; j++) {
+ (*d) |= (s[(i % 12) * 8 + j] & smask) ? dmask : 0;
+ dmask >>= 1;
+ }
+ d++;
+ }
+}
+
+static void sub_to_deinterleaved (const uae_u8 *s, uae_u8 *d)
+{
+ for (int i = 0; i < 8 * 12; i ++) {
+ int dmask = 0x80;
+ int smask = 1 << (7 - (i / 12));
+ (*d) = 0;
+ for (int j = 0; j < 8; j++) {
+ (*d) |= (s[(i % 12) * 8 + j] & smask) ? dmask : 0;
+ dmask >>= 1;
+ }
+ d++;
+ }
+}
+
static int spti_read (struct dev_info_ioctl *ciw, int unitnum, uae_u8 *data, int sector, int sectorsize)
{
uae_u8 cmd[12] = { 0xbe, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 };
cmd[9] |= 0x2 << 1; // C2
}
}
- ciw->cd_last_pos = sector;
cmd[3] = (uae_u8)(sector >> 16);
cmd[4] = (uae_u8)(sector >> 8);
cmd[5] = (uae_u8)(sector >> 0);
data += sectorsize;
ret += sectorsize;
}
- ciw->cd_last_pos = sector;
got = true;
}
}
ret += sectorsize;
}
}
- ciw->cd_last_pos = sector;
got = true;
} else {
reseterrormode (ciw);
ret += sectorsize;
}
}
- ciw->cd_last_pos = sector;
got = true;
}
}
MMRESULT mmr;
int volume[2], volume_main;
int oldplay;
+ int idleframes;
int readblocksize = 2352 + 96;
- int current_sector = -1;
for (i = 0; i < 2; i++) {
memset (&whdr[i], 0, sizeof (WAVEHDR));
bufon[bufnum] = 0;
if (oldplay != ciw->cdda_play) {
+ idleframes = 0;
struct _timeb tb1, tb2;
- current_sector = -1;
_ftime (&tb1);
cdda_pos = ciw->cdda_start;
+ ciw->cd_last_pos = cdda_pos;
oldplay = ciw->cdda_play;
write_log (L"IOCTL%s CDDA: playing from %d to %d\n",
ciw->usesptiread ? L"(SPTI)" : L"", ciw->cdda_start, ciw->cdda_end);
ciw->subcodevalid = false;
- while (ciw->cdda_paused && ciw->cdda_play > 0)
+ idleframes = ciw->cdda_delay_frames;
+ while (ciw->cdda_paused && ciw->cdda_play > 0) {
Sleep (10);
- // pre-load first sectors
- if (read_block (ciw, -1, px[bufnum], cdda_pos, num_sectors, readblocksize))
- current_sector = cdda_pos;
+ idleframes = -1;
+ }
+ // force spin up
+ read_block (ciw, -1, px[bufnum], cdda_pos, num_sectors, readblocksize);
+
+ if (ciw->cdda_scan == 0) {
+ // find possible P-subchannel=1 and fudge starting point so that
+ // buggy CD32/CDTV software CD+G handling does not miss any frames
+ bool seenindex = false;
+ for (int sector = cdda_pos - 200; sector < cdda_pos; sector++) {
+ uae_u8 *dst = px[bufnum];
+ if (sector >= 0 && read_block (ciw, -1, dst, sector, 1, readblocksize)) {
+ uae_u8 subbuf[SUB_CHANNEL_SIZE];
+ sub_deinterleave (dst + 2352, subbuf);
+ if (seenindex) {
+ for (int i = 2 * SUB_ENTRY_SIZE; i < SUB_CHANNEL_SIZE; i++) {
+ if (subbuf[i]) { // non-zero R-W subchannels
+ int diff = cdda_pos - sector + 2;
+ write_log (L"-> CD+G start pos fudge -> %d (%d)\n", sector, -diff);
+ idleframes -= diff;
+ cdda_pos = sector;
+ break;
+ }
+ }
+ } else if (subbuf[0] == 0xff) { // P == 1?
+ seenindex = true;
+ }
+ }
+ }
+ }
+ cdda_pos -= idleframes;
+
_ftime (&tb2);
int diff = (tb2.time * (uae_s64)1000 + tb2.millitm) - (tb1.time * (uae_s64)1000 + tb1.millitm);
diff -= ciw->cdda_delay;
- if (diff < 0 && ciw->cdda_play > 0)
+ if (idleframes >= 0 && diff < 0 && ciw->cdda_play > 0)
Sleep (-diff);
setstate (ciw, AUDIO_STATUS_IN_PROGRESS);
}
if ((cdda_pos < ciw->cdda_end || ciw->cdda_end == 0xffffffff) && !ciw->cdda_paused && ciw->cdda_play) {
- if (!isaudiotrack (&ciw->di.toc, cdda_pos)) {
+ if (idleframes <= 0 && !isaudiotrack (&ciw->di.toc, cdda_pos)) {
setstate (ciw, AUDIO_STATUS_PLAY_ERROR);
goto end; // data track?
}
gui_flicker_led (LED_CD, ciw->di.unitnum - 1, LED_CD_AUDIO);
uae_sem_wait (&ciw->sub_sem);
+
ciw->subcodevalid = false;
memset (ciw->subcode, 0, sizeof ciw->subcode);
-
- bool readerr = false;
- if (current_sector != cdda_pos) {
- current_sector = -1;
- memset (px[bufnum], 0, num_sectors * readblocksize);
- readerr = read_block (ciw, -1, px[bufnum], cdda_pos, num_sectors, readblocksize) == 0;
- if (!readerr)
- current_sector = cdda_pos;
- }
- if (readerr) {
- if (ciw->cdda_subfunc)
- ciw->cdda_subfunc (ciw->subcode, num_sectors);
- } else {
- for (i = 0; i < num_sectors; i++) {
- memcpy (ciw->subcode + i * SUB_CHANNEL_SIZE, px[bufnum] + readblocksize * i + 2352, SUB_CHANNEL_SIZE);
+ memset (px[bufnum], 0, num_sectors * readblocksize);
+
+ if (cdda_pos >= 0) {
+ if (read_block (ciw, -1, px[bufnum], cdda_pos, num_sectors, readblocksize)) {
+ for (i = 0; i < num_sectors; i++) {
+ memcpy (ciw->subcode + i * SUB_CHANNEL_SIZE, px[bufnum] + readblocksize * i + 2352, SUB_CHANNEL_SIZE);
+ }
+ for (i = 1; i < num_sectors; i++) {
+ memmove (px[bufnum] + 2352 * i, px[bufnum] + readblocksize * i, 2352);
+ }
+ ciw->subcodevalid = true;
}
- if (ciw->cdda_subfunc)
- ciw->cdda_subfunc (ciw->subcode, num_sectors);
- for (i = 1; i < num_sectors; i++) {
- memmove (px[bufnum] + 2352 * i, px[bufnum] + readblocksize * i, 2352);
+ }
+
+ for (i = 0; i < num_sectors; i++) {
+ if (idleframes > 0) {
+ idleframes--;
+ memset (px[bufnum] + 2352 * i, 0, 2352);
+ memset (ciw->subcode + i * SUB_CHANNEL_SIZE, 0, SUB_CHANNEL_SIZE);
+ } else if (cdda_pos < ciw->cdda_start && ciw->cdda_scan == 0) {
+ memset (px[bufnum] + 2352 * i, 0, 2352);
}
- ciw->subcodevalid = true;
}
- reseterrormode (ciw);
+ if (idleframes > 0)
+ ciw->subcodevalid = false;
+
+ if (ciw->cdda_subfunc)
+ ciw->cdda_subfunc (ciw->subcode, num_sectors);
uae_sem_post (&ciw->sub_sem);
if (cdda_pos < 0)
cdda_pos = 0;
} else {
- cdda_pos += num_sectors;
- }
- if (cdda_pos - num_sectors < ciw->cdda_end && cdda_pos >= ciw->cdda_end) {
- setstate (ciw, AUDIO_STATUS_PLAY_COMPLETE);
- ciw->cdda_play_finished = 1;
- ciw->cdda_play = -1;
- cdda_pos = ciw->cdda_end;
+ if (cdda_pos < 0 && cdda_pos + num_sectors >= 0)
+ cdda_pos = 0;
+ else
+ cdda_pos += num_sectors;
}
- ciw->cd_last_pos = cdda_pos;
+ if (idleframes <= 0) {
+ if (cdda_pos - num_sectors < ciw->cdda_end && cdda_pos >= ciw->cdda_end) {
+ setstate (ciw, AUDIO_STATUS_PLAY_COMPLETE);
+ ciw->cdda_play_finished = 1;
+ ciw->cdda_play = -1;
+ cdda_pos = ciw->cdda_end;
+ }
+ ciw->cd_last_pos = cdda_pos;
+ }
}
if (bufon[0] == 0 && bufon[1] == 0) {
ciw->cdda_statusfunc = statusfunc;
ciw->cdda_scan = scan > 0 ? 10 : (scan < 0 ? 10 : 0);
ciw->cdda_delay = setstate (ciw, -1);
+ ciw->cdda_delay_frames = setstate (ciw, -2);
setstate (ciw, AUDIO_STATUS_NOT_SUPPORTED);
if (!open_createfile (ciw, 0)) {
return 1;
}
-static void sub_deinterleave (const uae_u8 *s, uae_u8 *d)
-{
- for (int i = 0; i < 8 * 12; i ++) {
- int dmask = 0x80;
- int smask = 1 << (7 - (i / 12));
- (*d) = 0;
- for (int j = 0; j < 8; j++) {
- (*d) |= (s[(i % 12) * 8 + j] & smask) ? dmask : 0;
- dmask >>= 1;
- }
- d++;
- }
-}
-
-static void sub_to_deinterleaved (const uae_u8 *s, uae_u8 *d)
-{
- for (int i = 0; i < 8 * 12; i ++) {
- int dmask = 0x80;
- int smask = 1 << (7 - (i / 12));
- (*d) = 0;
- for (int j = 0; j < 8; j++) {
- (*d) |= (s[(i % 12) * 8 + j] & smask) ? dmask : 0;
- dmask >>= 1;
- }
- d++;
- }
-}
-
/* read qcode */
static int ioctl_command_qcode (int unitnum, uae_u8 *buf, int sector)
{
while (size-- > 0) {
if (!read_block (ciw, unitnum, data, sector, 1, sectorsize))
break;
+ ciw->cd_last_pos = sector;
data += sectorsize;
ret += sectorsize;
sector++;
reseterrormode (ciw);
return ret;
}
+ ciw->cd_last_pos = sector;
if (subs == 0) {
memcpy (data, p, blocksize);
Name : RetroPlatformIPC.h
Project : RetroPlatform Player
Client : Cloanto Italia srl
- Legal : Copyright 2007, 2008 Cloanto Italia srl - All rights reserved. This
+ Support : http://www.retroplatform.com
+ Legal : Copyright 2007-2010 Cloanto Italia srl - All rights reserved. This
: file is made available under the terms of the GNU General Public
: License version 2 as published by the Free Software Foundation.
Authors : os, mcb
Created : 2007-08-27 13:55:49
- Updated : 2008-12-19 12:38:00
+ Updated : 2010-08-17 19:01:00
Comment : RP Player interprocess communication include file
*****************************************************************************/
#include <windows.h>
-#define RPLATFORM_API_VER "1.1"
+#define RPLATFORM_API_VER "1.2"
#define RPLATFORM_API_VER_MAJOR 1
-#define RPLATFORM_API_VER_MINOR 1
+#define RPLATFORM_API_VER_MINOR 2
#define RPIPC_HostWndClass "RetroPlatformHost%s"
#define RPIPC_GuestWndClass "RetroPlatformGuest%d"
#define RPIPCGM_PARENT (WM_APP + 21)
#define RPIPCGM_DEVICESEEK (WM_APP + 22)
#define RPIPCGM_CLOSE (WM_APP + 23)
-
+#define RPIPCGM_DEVICEREADWRITE (WM_APP + 24)
+#define RPIPCGM_HOSTVERSION (WM_APP + 25)
// ****************************************************************************
// Host-to-Guest Messages
// ****************************************************************************
-#define RPIPCHM_CLOSE (WM_APP + 200)
-#define RPIPCHM_SCREENMODE (WM_APP + 202)
-#define RPIPCHM_SCREENCAPTURE (WM_APP + 203)
-#define RPIPCHM_PAUSE (WM_APP + 204)
-#define RPIPCHM_DEVICECONTENT (WM_APP + 205)
-#define RPIPCHM_RESET (WM_APP + 206)
-#define RPIPCHM_TURBO (WM_APP + 207)
-#define RPIPCHM_PING (WM_APP + 208)
-#define RPIPCHM_VOLUME (WM_APP + 209)
-#define RPIPCHM_ESCAPEKEY (WM_APP + 210)
-#define RPIPCHM_EVENT (WM_APP + 211)
-#define RPIPCHM_MOUSECAPTURE (WM_APP + 212)
-#define RPIPCHM_SAVESTATE (WM_APP + 213)
-#define RPIPCHM_LOADSTATE (WM_APP + 214)
-#define RPIPCHM_FLUSH (WM_APP + 215)
-
+#define RPIPCHM_CLOSE (WM_APP + 200)
+#define RPIPCHM_SCREENMODE (WM_APP + 202)
+#define RPIPCHM_SCREENCAPTURE (WM_APP + 203)
+#define RPIPCHM_PAUSE (WM_APP + 204)
+#define RPIPCHM_DEVICECONTENT (WM_APP + 205)
+#define RPIPCHM_RESET (WM_APP + 206)
+#define RPIPCHM_TURBO (WM_APP + 207)
+#define RPIPCHM_PING (WM_APP + 208)
+#define RPIPCHM_VOLUME (WM_APP + 209)
+#define RPIPCHM_ESCAPEKEY (WM_APP + 210)
+#define RPIPCHM_EVENT (WM_APP + 211)
+#define RPIPCHM_MOUSECAPTURE (WM_APP + 212)
+#define RPIPCHM_SAVESTATE (WM_APP + 213)
+#define RPIPCHM_LOADSTATE (WM_APP + 214)
+#define RPIPCHM_FLUSH (WM_APP + 215)
+#define RPIPCHM_DEVICEREADWRITE (WM_APP + 216)
// ****************************************************************************
// Message Data Structures and Defines
// ****************************************************************************
// Guest Features
-#define RP_FEATURE_POWERLED 0x00000001 // a power LED is emulated
-#define RP_FEATURE_SCREEN1X 0x00000002 // 1x mode is available
-#define RP_FEATURE_SCREEN2X 0x00000004 // 2x mode is available
-#define RP_FEATURE_SCREEN3X 0x00000008 // 3x mode is available
-#define RP_FEATURE_SCREEN4X 0x00000010 // 4x mode is available
-#define RP_FEATURE_FULLSCREEN 0x00000020 // full screen display is available
-#define RP_FEATURE_SCREENCAPTURE 0x00000040 // screen capture functionality is available (see RPIPCHM_SCREENCAPTURE message)
-#define RP_FEATURE_PAUSE 0x00000080 // pause functionality is available (see RPIPCHM_PAUSE message)
-#define RP_FEATURE_TURBO 0x00000100 // turbo mode functionality is available (see RPIPCHM_TURBO message)
-#define RP_FEATURE_VOLUME 0x00000200 // volume adjustment is possible (see RPIPCHM_VOLUME message)
-#define RP_FEATURE_STATE 0x00000400 // loading and saving of emulation state is supported (see RPIPCHM_SAVESTATE/RPIPCHM_LOADSTATE message)
-#define RP_FEATURE_SCANLINES 0x00000800 // scan lines video effect is available
+#define RP_FEATURE_POWERLED 0x00000001 // a power LED is emulated
+#define RP_FEATURE_SCREEN1X 0x00000002 // 1x mode is available
+#define RP_FEATURE_SCREEN2X 0x00000004 // 2x mode is available
+#define RP_FEATURE_SCREEN3X 0x00000008 // 3x mode is available
+#define RP_FEATURE_SCREEN4X 0x00000010 // 4x mode is available
+#define RP_FEATURE_FULLSCREEN 0x00000020 // full screen display is available
+#define RP_FEATURE_SCREENCAPTURE 0x00000040 // screen capture functionality is available (see RPIPCHM_SCREENCAPTURE message)
+#define RP_FEATURE_PAUSE 0x00000080 // pause functionality is available (see RPIPCHM_PAUSE message)
+#define RP_FEATURE_TURBO 0x00000100 // turbo mode functionality is available (see RPIPCHM_TURBO message)
+#define RP_FEATURE_VOLUME 0x00000200 // volume adjustment is possible (see RPIPCHM_VOLUME message)
+#define RP_FEATURE_STATE 0x00000400 // loading and saving of emulation state is supported (see RPIPCHM_SAVESTATE/RPIPCHM_LOADSTATE message)
+#define RP_FEATURE_SCANLINES 0x00000800 // scan lines video effect is available
+#define RP_FEATURE_DEVICEREADWRITE 0x00001000 // device read/write can be set at runtime on floppy and hard disks
// Screen Modes
#define RP_SCREENMODE_1X 0x00000000 // 1x window or full-screen mode ("CGA mode")
#define RP_IPD_KEYBDL2 L"KeyboardLayout2" // second joystick emulation keyboard layout (e.g. Keyboard Layout B for WinUAE)
#define RP_IPD_KEYBDL3 L"KeyboardLayout3" // third joystick emulation keyboard layout (e.g. Keyboard Layout C for WinUAE)
+// Joystick status flags
+#define RP_JOYSTICK_RIGHT 0x00000001 // right direction
+#define RP_JOYSTICK_LEFT 0x00000002 // left direction
+#define RP_JOYSTICK_DOWN 0x00000004 // down direction
+#define RP_JOYSTICK_UP 0x00000008 // up direction
+#define RP_JOYSTICK_BUTTON1 0x00000010 // button 1 - Fire 1 - CD32 Red
+#define RP_JOYSTICK_BUTTON2 0x00000020 // button 2 - Fire 2 - CD32 Blue
+#define RP_JOYSTICK_BUTTON3 0x00000040 // button 3 - Fire 3 - CD32 Yellow
+#define RP_JOYSTICK_BUTTON4 0x00000080 // button 4 - Fire 4 - CD32 Green
+#define RP_JOYSTICK_BUTTON5 0x00000100 // button 5 - CD32 Play
+#define RP_JOYSTICK_BUTTON6 0x00000200 // button 6 - CD32 Reverse
+#define RP_JOYSTICK_BUTTON7 0x00000400 // button 7 - CD32 Forward
+
+// Device Read/Write status
+#define RP_DEVICE_READONLY 0 // the medium is write-protected
+#define RP_DEVICE_READWRITE 1 // the medium is read/write
+
// Turbo Mode Functionalities
#define RP_TURBO_CPU 0x00000001 // CPU
#define RP_TURBO_FLOPPY 0x00000002 // floppy disk drive
// RPIPCGM_DEVICEACTIVITY
#define RP_DEVICEACTIVITY_GREEN 0x0000 // green led
#define RP_DEVICEACTIVITY_RED 0x0001 // red led
-#define RP_DEVICEACTIVITY_READ RP_DEVICEACTIVITY_GREEN // the device activity is about a read operation
-#define RP_DEVICEACTIVITY_WRITE RP_DEVICEACTIVITY_RED // the device activity is about a write operation
+#define RP_DEVICEACTIVITY_READ RP_DEVICEACTIVITY_GREEN // device activity is a read operation
+#define RP_DEVICEACTIVITY_WRITE RP_DEVICEACTIVITY_RED // device activity is a write operation
+
+// RPIPCGM_HOSTVERSION
+// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-----------------------+-------------------+-------------------+
+// | major | minor | build |
+// +-----------------------+-------------------+-------------------+
+#define RP_HOSTVERSION_MAJOR(ver) (((ver) >> 20) & 0xFFF)
+#define RP_HOSTVERSION_MINOR(ver) (((ver) >> 10) & 0x3FF)
+#define RP_HOSTVERSION_BUILD(ver) ((ver) & 0x3FF)
+#define RP_MAKE_HOSTVERSION(major,minor,build) ((LPARAM) (((LPARAM)((major) & 0xFFF)<<20) | ((LPARAM)((minor) & 0x3FF)<<10) | ((LPARAM)((build) & 0x3FF))))
+
#endif // __CLOANTO_RETROPLATFORMIPC_H__
Name : RetroPlatformIPC_doc.txt
Project : RPSampleGuest
Client : Cloanto Italia srl
+ Support : http://www.retroplatform.com
Legal : CONFIDENTIAL TRADE SECRET PROPERTY OF CLOANTO ITALIA SRL
- : Copyright © Cloanto Italia srl 2007-2008.
+ : Copyright © Cloanto Italia srl 2007-2009.
: All rights reserved, except where licensed,
: assigned or transferred by contract.
Authors : os, mcb
RPIPCGM_POWERLED (turns on the power LED in the GUI),
RPIPCGM_DEVICES (one for each device category: tells the number of emulated devices),
RPIPCGM_DEVICECONTENT (one for each device with an image file or peripheral attached),
+ RPIPCGM_DEVICEREADWRITE (one for each device with an image file or peripheral attached - optional for non-floppy/non-hard disk which are always read-only),
RPIPCGM_TURBO (tells if some of the turbo modes are activated from the start),
RPIPCGM_VOLUME (reports about starting volume level),
RPIPCGM_SCREENMODE (communicates the screen mode, the clipping coordinates and the guest window handle);
and send its handle using a RPIPCGM_SCREENMODE message, which must be the last
of the initialization messages, since it displays the guest window
and the host "frame window" (the part of the player user interface
- with command and status icons which can be used to drag the guest window, etc.)
+ with command and status icons which can be used to drag the guest window, etc.);
+ in some circumstances the host may decide not to display the guest window
+ when receiving the RPIPCGM_SCREENMODE message (e.g. in Express mode
+ the guest may be immediately paused and an intro banner may be displayed;
+ when the intro banner is dismissed the guest is resumed from pause mode
+ and its window is displayed)
Data sent:
WPARAM = RP_FEATURE_* flags
Response:
RPIPCGM_DEVICEACTIVITY
Description:
this message can be used to turn on or off the activity indicator
- of a specified device (like a LED on the original hardware);
+ of a specified device (like a LED on the original hardware)
+ or to notify the host about the status of a joystick;
the indicator can also be "blinked", i.e. the host will turn the
LED on and then off again after the specified amount of time
Data sent:
or to a <millisecond delay> value to turn on the activity LED
for the specified amount of time (blink);
the Flags value can be set
- using one or more of the RP_DEVICEACTIVITY_* defines
+ using one or more of the RP_DEVICEACTIVITY_* defines;
+ in case the message references a RP_DEVICE_INPUTPORT device
+ connected to a joystick, the data sent via LPARAM
+ is a combination of RP_JOYSTICK_* values
Response:
none
(e.g. LOWORD(lr) = major version; HIWORD(lr) = minor version)
+Message:
+ RPIPCGM_HOSTVERSION
+Description:
+ the guest can send a RPIPCGM_HOSTVERSION
+ to query the host about its version
+Data sent:
+ none
+Response:
+ LRESULT = major, minor and build versions combined into a single 32 bit value;
+ the RP_HOSTVERSION_* macros can be used to get specific information
+
+
Message:
RPIPCGM_PAUSE
Description:
pData = a RPDEVICECONTENT structure (see RetroPlatformIPC.h);
the szContent field of the structure
contains an empty string when the guest
- is ejecting something from the device
+ is ejecting something from the device;
+ szContent examples for CD and other physical drives supported by the guest:
+ - "D:\" = mount physical drive D: (full or empty, does not matter)
+ - "C:\test.iso" = mount ISO image
+ - "" = empty image drive ("image mode without image")
+ - there is no specific message to indicate "empty physical drive" (what counts is that there is an association with the physical drive)
+Response:
+ none
+
+
+Message:
+ RPIPCGM_DEVICEREADWRITE
+Description:
+ the guest sends a RPIPCGM_DEVICEREADWRITE message
+ to notify the host about an initial status or a change in
+ the read/write protection status;
+ this notification is optional if the event
+ was requested by the host (see the RPIPCHM_DEVICEREADWRITE message);
+ if no initial status is sent, the status is assumed to be read/write
+ for floppy and hard disks, and read-only for all other devices
+ (CDs, cartridges, tapes, etc.)
+Data sent:
+ WPARAM = device category (RP_DEVICE_* value) and device number
+ combined with the MAKEWORD macro;
+ e.g. MAKEWORD(RP_DEVICE_FLOPPY, 0)
+ LPARAM = current device read/write status flags (RP_DEVICE_READONLY/RP_DEVICE_READWRITE)
Response:
none
LRESULT = 1 if the guest successfully executed the command or 0 otherwise
+Message:
+ RPIPCHM_DEVICEREADWRITE
+Description:
+ the host sends a RPIPCHM_DEVICEREADWRITE message
+ to set the read/write protection status
+Data sent:
+ WPARAM = device category (RP_DEVICE_* value) and device number
+ combined with the MAKEWORD macro;
+ e.g. MAKEWORD(RP_DEVICE_FLOPPY, 0)
+ LPARAM = current device read/write status flags (RP_DEVICE_READONLY/RP_DEVICE_READWRITE)
+Response:
+ LRESULT = 1 if the guest successfully executed the command or 0 otherwise (for example, because the image file itself is read-only, so that writing is not possible)
+
+
Message:
RPIPCHM_RESET
Description:
static int normalmouse, supermouse, rawmouse, winmouse, winmousenumber, winmousemode, winmousewheelbuttonstart;
static int normalkb, superkb, rawkb;
static bool rawinput_enabled_mouse, rawinput_enabled_keyboard;
+static bool rawinput_decided;
int no_rawinput = 0;
int dinput_enum_all;
static void addrkblabels (struct didata *did)
{
- int j = 0;
for (int k = 0; k < 254; k++) {
TCHAR tmp[100];
tmp[0] = 0;
- if (rawkeyboardlabels[j] != NULL) {
- if (rawkeyboardlabels[j][0]) {
- _tcscpy (tmp, rawkeyboardlabels[j]);
- j++;
- }
- } else {
- j++;
- }
+ if (rawkeyboardlabels[k] != NULL && rawkeyboardlabels[k][0])
+ _tcscpy (tmp, rawkeyboardlabels[k]);
if (!tmp[0])
_stprintf (tmp, L"KEY_%02X", k + 1);
did->buttonname[k] = my_strdup (tmp);
PRID_DEVICE_INFO rdi;
int v, j;
+ if (rawinput_decided) {
+ // must not enable rawinput later, even if rawinput capable device was plugged in
+ if (type == RIM_TYPEKEYBOARD && !rawinput_enabled_keyboard)
+ continue;
+ if (type == RIM_TYPEMOUSE && !rawinput_enabled_mouse)
+ continue;
+ }
+
if (GetRawInputDeviceInfo (h, RIDI_DEVICENAME, NULL, &vtmp) == -1)
continue;
if (vtmp >= bufsize)
write_log (L"RawInput enumeration..\n");
initialize_rawinput ();
}
- rawinput_enabled_keyboard = num_keyboard > 0;
- rawinput_enabled_mouse = num_mouse > 0;
+
+ if (!rawinput_decided) {
+ rawinput_enabled_keyboard = num_keyboard > 0;
+ rawinput_enabled_mouse = num_mouse > 0;
+ rawinput_decided = true;
+ }
hr = DirectInput8Create (hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID *)&g_lpdi, NULL);
if (FAILED(hr)) {
static void D3D_render22 (void)
{
HRESULT hr;
- LPDIRECT3DTEXTURE9 srctex;
+ LPDIRECT3DTEXTURE9 srctex = texture;
UINT uPasses, uPass;
if (!isd3d ())
#endif
srctex = lpTempTexture;
- } else {
-
- srctex = texture;
-
}
}
}
}
-int uae_start_thread (TCHAR *name, void *(*f)(void *), void *arg, uae_thread_id *tid)
+int uae_start_thread (const TCHAR *name, void *(*f)(void *), void *arg, uae_thread_id *tid)
{
HANDLE hThread;
int result = 1;
static int initialized;
static RPGUESTINFO guestinfo;
+static int maxjports;
TCHAR *rp_param = NULL;
int rp_rpescapekey = 0x01;
int rp_screenmode = 0;
int rp_inputmode = 0;
int log_rp = 1;
+static int rp_revision, rp_version, rp_build;
static int max_horiz_dbl = RES_HIRES;
static int max_vert_dbl = 1;
static int rp_filter, rp_filter_default;
static int recursive_device, recursive;
static int currentpausemode;
+static int gameportmask[MAX_JPORTS];
static int cando (void)
{
case RPIPCGM_REGISTER: return L"RPIPCGM_REGISTER";
case RPIPCGM_FEATURES: return L"RPIPCGM_FEATURES";
case RPIPCGM_CLOSED: return L"RPIPCGM_CLOSED";
- case RPIPCGM_CLOSE: return L"RPIPCGM_CLOSE";
case RPIPCGM_ACTIVATED: return L"RPIPCGM_ACTIVATED";
case RPIPCGM_DEACTIVATED: return L"RPIPCGM_DEACTIVATED";
- case RPIPCGM_PARENT: return L"RPIPCGM_PARENT";
case RPIPCGM_SCREENMODE: return L"RPIPCGM_SCREENMODE";
case RPIPCGM_POWERLED: return L"RPIPCGM_POWERLED";
case RPIPCGM_DEVICES: return L"RPIPCGM_DEVICES";
case RPIPCGM_MOUSECAPTURE: return L"RPIPCGM_MOUSECAPTURE";
case RPIPCGM_HOSTAPIVERSION: return L"RPIPCGM_HOSTAPIVERSION";
case RPIPCGM_PAUSE: return L"RPIPCGM_PAUSE";
+ case RPIPCGM_DEVICECONTENT: return L"RPIPCGM_DEVICECONTENT";
case RPIPCGM_TURBO: return L"RPIPCGM_TURBO";
+ case RPIPCGM_PING: return L"RPIPCGM_PING";
case RPIPCGM_VOLUME: return L"RPIPCGM_VOLUME";
- case RPIPCGM_DEVICECONTENT: return L"RPIPCGM_DEVICECONTENT";
- case RPIPCGM_DEVICESEEK: return L"RPIPCGM_DEVICESEEK";
case RPIPCGM_ESCAPED: return L"RPIPCGM_ESCAPED";
+ case RPIPCGM_PARENT: return L"RPIPCGM_PARENT";
+ case RPIPCGM_DEVICESEEK: return L"RPIPCGM_DEVICESEEK";
+ case RPIPCGM_CLOSE: return L"RPIPCGM_CLOSE";
+ case RPIPCGM_DEVICEREADWRITE: return L"RPIPCGM_DEVICEREADWRITE";
+ case RPIPCGM_HOSTVERSION: return L"RPIPCGM_HOSTVERSION";
case RPIPCHM_CLOSE: return L"RPIPCHM_CLOSE";
case RPIPCHM_SCREENMODE: return L"RPIPCHM_SCREENMODE";
case RPIPCHM_SCREENCAPTURE: return L"RPIPCHM_SCREENCAPTURE";
case RPIPCHM_PAUSE: return L"RPIPCHM_PAUSE";
+ case RPIPCHM_DEVICECONTENT: return L"RPIPCHM_DEVICECONTENT";
case RPIPCHM_RESET: return L"RPIPCHM_RESET";
case RPIPCHM_TURBO: return L"RPIPCHM_TURBO";
+ case RPIPCHM_PING: return L"RPIPCHM_PING";
case RPIPCHM_VOLUME: return L"RPIPCHM_VOLUME";
- case RPIPCHM_EVENT: return L"RPIPCHM_EVENT";
case RPIPCHM_ESCAPEKEY: return L"RPIPCHM_ESCAPEKEY";
+ case RPIPCHM_EVENT: return L"RPIPCHM_EVENT";
case RPIPCHM_MOUSECAPTURE: return L"RPIPCHM_MOUSECAPTURE";
- case RPIPCHM_DEVICECONTENT: return L"RPIPCHM_DEVICECONTENT";
- case RPIPCHM_PING: return L"RPIPCHM_PING";
case RPIPCHM_SAVESTATE: return L"RPIPCHM_SAVESTATE";
case RPIPCHM_LOADSTATE: return L"RPIPCHM_LOADSTATE";
case RPIPCHM_FLUSH: return L"RPIPCHM_FLUSH";
+ case RPIPCHM_DEVICEREADWRITE: return L"RPIPCHM_DEVICEREADWRITE";
default: return L"UNKNOWN";
}
{
TCHAR tmp1[1000];
- if (num < 0 || num >= MAX_JPORTS)
+ if (num < 0 || num >= maxjports)
return FALSE;
if (_tcslen (name) == 0) {
inputdevice_joyport_config (&changed_prefs, L"none", num, 0, 0);
}
return ret;
}
+ case RPIPCHM_DEVICEREADWRITE:
+ {
+ DWORD ret = FALSE;
+ int device = LOBYTE(wParam);
+ if (device == RP_DEVICE_FLOPPY) {
+ int num = HIBYTE(wParam);
+ if (lParam == RP_DEVICE_READONLY || lParam == RP_DEVICE_READWRITE) {
+ ret = disk_setwriteprotect (num, currprefs.floppyslots[num].df, lParam == RP_DEVICE_READONLY);
+ }
+ }
+ return ret ? (LPARAM)1 : 0;
+ }
}
return FALSE;
}
return lr;
}
+static int rp_hostversion (int *ver, int *rev, int *build)
+{
+ LRESULT lr = 0;
+ if (!RPSendMessagex (RPIPCGM_HOSTVERSION, 0, 0, NULL, 0, &guestinfo, &lr))
+ return 0;
+ *ver = RP_HOSTVERSION_MAJOR(lr);
+ *rev = RP_HOSTVERSION_MINOR(lr);
+ *build = RP_HOSTVERSION_BUILD(lr);
+ return 1;
+}
+
HRESULT rp_init (void)
{
HRESULT hr;
hr = RPInitializeGuest (&guestinfo, hInst, rp_param, RPHostMsgFunction, 0);
if (SUCCEEDED (hr)) {
initialized = TRUE;
- write_log (L"rp_init('%s') succeeded\n", rp_param);
+ rp_version = rp_revision = rp_build = -1;
+ rp_hostversion (&rp_version, &rp_revision, &rp_build);
+ write_log (L"rp_init('%s') succeeded. Version: %d.%d.%d\n", rp_param, rp_version, rp_revision, rp_build);
} else {
write_log (L"rp_init('%s') failed, error code %08x\n", rp_param, hr);
}
RPUninitializeGuest (&guestinfo);
}
+
int rp_close (void)
{
if (!cando ())
feat = RP_FEATURE_POWERLED | RP_FEATURE_SCREEN1X | RP_FEATURE_FULLSCREEN;
feat |= RP_FEATURE_PAUSE | RP_FEATURE_TURBO | RP_FEATURE_VOLUME | RP_FEATURE_SCREENCAPTURE;
- feat |= RP_FEATURE_STATE | RP_FEATURE_SCANLINES;
+ feat |= RP_FEATURE_STATE | RP_FEATURE_SCANLINES | RP_FEATURE_DEVICEREADWRITE;
if (!WIN32GFX_IsPicassoScreen ())
feat |= RP_FEATURE_SCREEN2X | RP_FEATURE_SCREEN4X;
RPSendMessagex (RPIPCGM_FEATURES, feat, 0, NULL, 0, &guestinfo, NULL);
max_horiz_dbl = currprefs.gfx_max_horizontal;
max_vert_dbl = currprefs.gfx_max_vertical;
+ maxjports = (rp_version * 256 + rp_revision) >= 2 * 256 + 3 ? MAX_JPORTS : 2;
changed_prefs.win32_borderless = currprefs.win32_borderless = 1;
rp_filter_default = rp_filter = currprefs.gfx_filter;
}
RPSendMessagex (RPIPCGM_DEVICES, RP_DEVICE_FLOPPY, floppy_mask, NULL, 0, &guestinfo, NULL);
- RPSendMessagex (RPIPCGM_DEVICES, RP_DEVICE_INPUTPORT, (1 << MAX_JPORTS) - 1, NULL, 0, &guestinfo, NULL);
+ RPSendMessagex (RPIPCGM_DEVICES, RP_DEVICE_INPUTPORT, (1 << maxjports) - 1, NULL, 0, &guestinfo, NULL);
rp_input_change (0);
rp_input_change (1);
rp_input_change (2);
rp_input_change (3);
+ gameportmask[0] = gameportmask[1] = gameportmask[2] = gameportmask[3] = 0;
hd_mask = 0;
cd_mask = 0;
}
}
-
rp_update_volume (&currprefs);
rp_turbo (currprefs.turbo_emulation);
for (i = 0; i <= 4; i++)
config_changed = 1;
}
+static void rp_device_writeprotect (int dev, int num, bool writeprotected)
+{
+ if (!cando ())
+ return;
+ if (rp_version * 256 + rp_revision < 2 * 256 + 3)
+ return;
+ RPSendMessagex (RPIPCGM_DEVICEREADWRITE, MAKEWORD(dev, num), writeprotected ? RP_DEVICE_READONLY : RP_DEVICE_READWRITE, NULL, 0, &guestinfo, NULL);
+}
+
static void rp_device_change (int dev, int num, const TCHAR *name)
{
struct RPDeviceContent *dc;
TCHAR name[MAX_DPATH];
TCHAR *name2 = NULL, *name3 = NULL;
+ if (num >= maxjports)
+ return;
+
name[0] = 0;
if (JSEM_ISXARCADE1 (num, &currprefs)) {
j = 2;
}
rp_device_change (RP_DEVICE_INPUTPORT, num, name);
}
-void rp_disk_image_change (int num, const TCHAR *name)
+void rp_disk_image_change (int num, const TCHAR *name, bool writeprotected)
{
rp_device_change (RP_DEVICE_FLOPPY, num, name);
+ rp_device_writeprotect (RP_DEVICE_FLOPPY, num, writeprotected);
}
void rp_harddrive_image_change (int num, const TCHAR *name)
{
}
}
+void rp_update_gameport (int port, int mask, int onoff)
+{
+ if (!cando ())
+ return;
+ if (port < 0 || port >= maxjports)
+ return;
+ if (rp_version * 256 + rp_revision < 2 * 256 + 3)
+ return;
+ int old = gameportmask[port];
+ if (onoff)
+ gameportmask[port] |= mask;
+ else
+ gameportmask[port] &= ~mask;
+ if (old != gameportmask[port])
+ RPPostMessagex (RPIPCGM_DEVICEACTIVITY, MAKEWORD (RP_DEVICE_INPUTPORT, port),
+ gameportmask[port], &guestinfo);
+}
+
void rp_hd_activity (int num, int onoff, int write)
{
if (!cando ())
extern void rp_free (void);
extern int rp_close (void);
extern void rp_fixup_options (struct uae_prefs*);
-extern void rp_update_volume (struct uae_prefs*);
extern void rp_pause (int paused);
-extern void rp_update_leds (int, int, int);
-extern void rp_floppy_track (int floppy, int track);
-extern void rp_floppydrive_change (int num, int removed);
-extern void rp_hd_activity (int, int, int);
-extern void rp_hd_change (int, int);
-extern void rp_cd_activity (int, int);
-extern void rp_cd_change (int, int);
extern void rp_activate (int, LPARAM);
extern void rp_mouse_capture (int);
extern void rp_mouse_magic (int);
extern int log_rp;
extern void rp_input_change (int num);
-extern void rp_disk_image_change (int num, const TCHAR *name);
+extern void rp_disk_image_change (int num, const TCHAR *name, bool writeprotected);
extern void rp_harddrive_image_change (int num, const TCHAR *name);
extern void rp_cd_image_change (int num, const TCHAR *name);
+
+extern void rp_update_gameport (int port, int mask, int onoff);
+extern void rp_update_volume (struct uae_prefs*);
+extern void rp_update_leds (int, int, int);
+extern void rp_floppy_track (int floppy, int track);
+extern void rp_floppydrive_change (int num, int removed);
+extern void rp_hd_activity (int, int, int);
+extern void rp_hd_change (int, int);
+extern void rp_cd_activity (int, int);
+extern void rp_cd_change (int, int);
extern void uae_sem_post (uae_sem_t*);
extern void uae_sem_wait (uae_sem_t*t);
extern void uae_sem_init (uae_sem_t*, int manual_reset, int initial_state);
-extern int uae_start_thread (TCHAR *name, void *(*f)(void *), void *arg, uae_thread_id *thread);
+extern int uae_start_thread (const TCHAR *name, void *(*f)(void *), void *arg, uae_thread_id *thread);
extern int uae_start_thread_fast (void *(*f)(void *), void *arg, uae_thread_id *thread);
extern void uae_end_thread (uae_thread_id *thread);
extern void uae_set_thread_priority (uae_thread_id *, int);
} else {
oc = SetTextColor (lpDIS->hDC, GetSysColor ((tflags & 2) ? COLOR_BTNTEXT : COLOR_GRAYTEXT));
}
- flags = DT_VCENTER | DT_SINGLELINE ;
+ flags = DT_VCENTER | DT_SINGLELINE;
if (tflags & 1) {
flags |= DT_CENTER;
lpDIS->rcItem.left++;
g_dwBackgroundColor = RGB (255, 0, 255);
ReleaseDC (NULL, hDC);
- wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_DBLCLKS | CS_OWNDC;
+ wc.style = CS_DBLCLKS | CS_OWNDC;
wc.lpfnWndProc = AmigaWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInst;
wc.hIcon = LoadIcon (GetModuleHandle (NULL), MAKEINTRESOURCE (IDI_APPICON));
- wc.hCursor = NULL; //LoadCursor (NULL, IDC_ARROW);
+ wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.lpszMenuName = 0;
wc.lpszClassName = L"AmigaPowah";
wc.hbrBackground = CreateSolidBrush (g_dwBackgroundColor);
if (!RegisterClass (&wc))
return 0;
- wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
+ wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInst;
wc.hIcon = LoadIcon (GetModuleHandle (NULL), MAKEINTRESOURCE (IDI_APPICON));
- wc.hCursor = NULL; //LoadCursor (NULL, IDC_ARROW);
+ wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = CreateSolidBrush (black);
wc.lpszMenuName = 0;
wc.lpszClassName = L"PCsuxRox";
if (!RegisterClass (&wc))
return 0;
- wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW;
+ wc.style = 0;
wc.lpfnWndProc = HiddenWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInst;
wc.hIcon = LoadIcon (GetModuleHandle (NULL), MAKEINTRESOURCE (IDI_APPICON));
- wc.hCursor = NULL; //LoadCursor (NULL, IDC_ARROW);
+ wc.hCursor = NULL;
wc.hbrBackground = CreateSolidBrush (g_dwBackgroundColor);
wc.lpszMenuName = 0;
wc.lpszClassName = L"Useless";
{
if (path[0] == 0 || (path[0] == '\\' && path[1] == '\\') || path[0] == ':')
return;
+ /* <drive letter>: is supposed to mean same as <drive letter>:\ */
+ if (_istalpha (path[0]) && path[1] == ':' && path[2] == 0)
+ _tcscat (path, L"\\");
if (relativepaths) {
TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH];
tmp1[0] = 0;
log_scsi = 1;
return 1;
}
+ if (!_tcscmp (arg, L"scsiemulog")) {
+ extern int log_scsiemu;
+ log_scsiemu = 1;
+ return 1;
+ }
if (!_tcscmp (arg, L"netlog")) {
log_net = 1;
return 1;
#define WINUAEPUBLICBETA 1
#define LANG_DLL 1
-#define WINUAEBETA L"10"
-#define WINUAEDATE MAKEBD(2010, 8, 11)
+#define WINUAEBETA L"12"
+#define WINUAEDATE MAKEBD(2010, 8, 21)
#define WINUAEEXTRA L""
#define WINUAEREV L""
{
if (!usedfilter)
return 1;
+ if (screen_is_picasso)
+ return 1;
return usedfilter->intmul;
}
#ifdef D3D
if (currentmode->flags & DM_D3D) {
const TCHAR *err = D3D_init (hAmigaWnd, currentmode->native_width, currentmode->native_height,
- currentmode->amiga_width, currentmode->amiga_height, currentmode->current_depth, currprefs.gfx_filter_filtermode + 1);
+ currentmode->amiga_width, currentmode->amiga_height, currentmode->current_depth, screen_is_picasso ? 1 : currprefs.gfx_filter_filtermode + 1);
if (err) {
D3D_free ();
gui_message (err);
addfloppyhistory (hDlg);
}
-static void floppysetwriteprotect (HWND hDlg, int n, int protect)
+static void floppysetwriteprotect (HWND hDlg, int n, bool writeprotected)
{
if (!iscd (n)) {
- disk_setwriteprotect (n, workprefs.floppyslots[n].df, protect);
+ disk_setwriteprotect (n, workprefs.floppyslots[n].df, writeprotected);
addfloppytype (hDlg, n);
}
}
{
}
-void gui_disk_image_change (int unitnum, const TCHAR *name)
+void gui_disk_image_change (int unitnum, const TCHAR *name, bool writeprotected)
{
#ifdef RETROPLATFORM
- rp_disk_image_change (unitnum, name);
+ rp_disk_image_change (unitnum, name, writeprotected);
#endif
}
+Beta 12:
+
+- <drive letter>: without '\' in harddrive paths was detected as a relative path,
+ automatically add missing '\', it was commonly used in old config files
+- CD32 pad in 2-button mode usually returned non-existing 3rd button pressed
+- CD32 pad in 2-button mode didn't have pullup resistor emulation (was lost when
+ joystick pullups were removed in 2.2)
+- autocorrect CD32/CDTV CDA starting position if R-W subchannel data is detected, workaround
+ for a bug (happens on real CD32 and CDTV too) that can cause missed subchannel frames at
+ play startup causing corrupt or missing CD+G graphics
+- CD thread safety critical sections moved to common part from image mounter
+- CD image mounter in play state while replacing image: state was still reported as playing
+- do not enable rawinput if rawinput capable device is inserted after winuae has been started
+- 2x or larger filters changed RTG hardware mouse cursor size.. (D3D + hardware RTG cursor only)
+- scsi emulation always-on logging disabled, added -scsiemulog command line parameter
+
+Beta 11:
+
+- internal CD audio handling update, status change (starting, started, end, error) callback
+ added, CD32 and CDTV emulation does not poll for state changes anymore, better accuracy
+ in audio start and end timing. CD handling rewrite should be complete now.
+- CD image mounter is now thread safe, no more weird and random behavior if mounted image was
+ in use and image was ejected or replaced
+- fixed rare crash in display emulation (introduced when right border blanking update was added)
+- improved CD32 CD sound/animation timing
+- CD32 CD timing now works correctly in NTSC mode (previously used hardcoded PAL values)
+- "non-path" kickstart rom configuration file selection now only allows normal KS roms in
+ kickstart_rom variable and extended roms in kickstart_rom_ext variable
+- fixed D3D non-shader mode crash introduced in b9
+- bogus autofire mode was enabled if same joystick was custom configured in input panel and in gameports panel
+ (missing masking of flags variable, time to wear brown paper bag again..)
+
Beta 10:
- archive dragndrop worked too well, it unpacked everything, including adf filesystem etc..
PW_l = (((in_data[PW_Start_Address+PW_j*8+4]*256)+in_data[PW_Start_Address+5+PW_j*8])*2);
/* loop size */
PW_m = (((in_data[PW_Start_Address+PW_j*8+6]*256)+in_data[PW_Start_Address+7+PW_j*8])*2);
- if ( (PW_m == 0) || (PW_m == PW_l) )
+ if ( PW_m == 0 )
{
/*printf ( "#1,98 (start:%ld) (PW_k:%ld) (PW_l:%ld) (PW_m:%ld)\n" , PW_Start_Address,PW_k,PW_l,PW_m );*/
return BAD;
return BAD;
}
}
+
if ( PW_WholeSampleSize <= 2 )
{
/*printf ( "#2,4 (start:%ld)\n" , PW_Start_Address );*/
if ( PW_Start_Address + 762 + (PW_k*4) > PW_in_size )
{
+/*printf ( "#4 (start:%ld)\n" , PW_Start_Address );*/
return BAD;
}
-
/* track data test */
PW_l=0;
for ( PW_j=0 ; PW_j<PW_k ; PW_j++ )
}
if ( ((in_data[PW_Start_Address+762+PW_j*4]&0x0f) == 0x00 ) && (in_data[PW_Start_Address+763+PW_j*4] < 0x71) && (in_data[PW_Start_Address+763+PW_j*4] != 0x00))
{
- /* printf ( "#3,2 (start:%ld)(where:%ld)\n",PW_Start_Address,762+PW_j*4 );*/
+/*printf ( "#3,2 (start:%ld)(where:%ld)\n",PW_Start_Address,762+PW_j*4 );*/
return BAD;
}
if ( ((in_data[PW_Start_Address+762+PW_j*4]&0x0f) != 0x00 ) || (in_data[PW_Start_Address+763+PW_j*4] != 0x00 ))
* - overall speed and size optimizings.
* Update: 19/04/00 (all pointed out by Thomas Neumann)
* - replen bug correction
+ * Update: 15/05/10
+ * - rewrote depacker for patternlist generation
*/
void Depack_PP10 ( void )
{
- Uchar Tracks_Numbers[4][128];
- Uchar Pat_Pos;
- Uchar *Whatever;
- short Max;
- long i=0,j=0,k=0;
+ Uchar *Header, *Pattern;
+ Ulong ReadTrkPat[128][4], ReadPat[128];
+ long Highest_Track = 0;
+ long i=0,j=0,k=0,l=0,m=0;
long WholeSampleSize=0;
long Where=PW_Start_Address;
FILE *out;
if ( Save_Status == BAD )
return;
- BZERO ( Tracks_Numbers , 128*4 );
-
sprintf ( Depacked_OutName , "%ld.mod" , Cpt_Filename-1 );
out = PW_fopen ( Depacked_OutName , "w+b" );
- /* write title */
- Whatever = (Uchar *) malloc (1024);
- BZERO ( Whatever , 1024 );
- fwrite ( Whatever , 20 , 1 , out );
+ Header = (Uchar *)malloc(1084);
+ Pattern = (Uchar *)malloc(1024);
+ BZERO ( Header , 1084 );
+ BZERO ( Pattern , 1024 );
/* read and write sample descriptions */
for ( i=0 ; i<31 ; i++ )
{
- /*sample name*/
- fwrite ( Whatever , 22 , 1 , out );
-
WholeSampleSize += (((in_data[Where]*256)+in_data[Where+1])*2);
- fwrite ( &in_data[Where] , 6 , 1 , out );
-
- Whatever[32] = in_data[Where+6];
- Whatever[33] = in_data[Where+7];
+ /* siz,fine,vol,lstart,lsize */
+ Header[42+i*30] = in_data[Where];
+ Header[43+i*30] = in_data[Where+1];
+ Header[44+i*30] = in_data[Where+2];
+ Header[45+i*30] = in_data[Where+3];
+ Header[46+i*30] = in_data[Where+4];
+ Header[47+i*30] = in_data[Where+5];
+ Header[48+i*30] = in_data[Where+6];
+ Header[49+i*30] = in_data[Where+7];
if ( (in_data[Where+6] == 0x00) && (in_data[Where+7] == 0x00) )
- Whatever[33] = 0x01;
- fwrite ( &Whatever[32] , 2 , 1 , out );
+ Header[49+i*30] = 0x01;
Where += 8;
}
/*printf ( "Whole sample size : %ld\n" , WholeSampleSize );*/
/* read and write pattern table lenght */
- Pat_Pos = in_data[Where++];
- fwrite ( &Pat_Pos , 1 , 1 , out );
- /*printf ( "Size of pattern list : %d\n" , Pat_Pos );*/
+ Header[950] = in_data[Where];
+ Where += 1;
+ /*printf ( "Size of pattern list : %d\n" , Header[950] );*/
/* read and write NoiseTracker byte */
- fwrite ( &in_data[Where++] , 1 , 1 , out );
+ Header[951] = in_data[Where];
+ Where += 1;
- /* read track list and get highest track number */
- Max = 0;
- for ( j=0 ; j<4 ; j++ )
+ // now, where = 0xFA
+ for (i=0;i<Header[950];i++)
{
- for ( i=0 ; i<128 ; i++ )
- {
- Tracks_Numbers[j][i] = in_data[Where++];
- if ( Tracks_Numbers[j][i] > Max )
- Max = Tracks_Numbers[j][i];
- }
+ ReadPat[i] = (in_data[Where+i]*256*256*256) +
+ (in_data[Where+i+128]*256*256) +
+ (in_data[Where+i+256]*256) +
+ in_data[Where+i+384];
+ ReadTrkPat[i][0] = in_data[Where+i];
+ ReadTrkPat[i][1] = in_data[Where+i+128];
+ ReadTrkPat[i][2] = in_data[Where+i+256];
+ ReadTrkPat[i][3] = in_data[Where+i+384];
+ if (ReadTrkPat[i][0] > Highest_Track)
+ Highest_Track = ReadTrkPat[i][0];
+ if (ReadTrkPat[i][1] > Highest_Track)
+ Highest_Track = ReadTrkPat[i][1];
+ if (ReadTrkPat[i][2] > Highest_Track)
+ Highest_Track = ReadTrkPat[i][2];
+ if (ReadTrkPat[i][3] > Highest_Track)
+ Highest_Track = ReadTrkPat[i][3];
+ /*printf ("%x-%x-%x-%x\n",ReadTrkPat[i][0],ReadTrkPat[i][1],ReadTrkPat[i][2],ReadTrkPat[i][3]);*/
+ }
+ /*printf ( "Number of tracks : %d\n" , Highest_Track+1 );*/
+
+ /* sorting ?*/
+ k = 0; /* next min */
+ l = 0;
+
+ /* put the first pattern number */
+ /* could be stored several times */
+ for (j=0; j<Header[950] ; j++)
+ {
+ m = 0x7fffffff; /* min */
+ /*search for min */
+ for (i=0; i<Header[950] ; i++)
+ if ((ReadPat[i]<m) && (ReadPat[i]>k))
+ m = ReadPat[i];
+ /* if k == m then an already existing ref was found */
+ if (k==m)
+ continue;
+ /* m is the next minimum */
+ k = m;
+ for (i=0; i<Header[950] ; i++)
+ if (ReadPat[i] == k)
+ Header[952+i] = (unsigned char)l;
+ l++;
}
- /*printf ( "highest track number : %d\n" , Max+1 );*/
+ if ( l != Header[950] )
+ l -= 1;
- /* write pattern table "as is" ... */
- for (Whatever[0]=0 ; Whatever[0]<Pat_Pos ; Whatever[0]+=0x01 )
- fwrite ( &Whatever[0] , 1 , 1 , out );
- fwrite ( &Whatever[256] , (128-Pat_Pos) , 1 , out );
- /* Where is reassigned later */
/* write ptk's ID */
- Whatever[0] = 'M';
- Whatever[1] = '.';
- Whatever[2] = 'K';
- Whatever[3] = '.';
- fwrite ( Whatever , 4 , 1 , out );
+ Header[1080] = 'M';
+ Header[1081] = Header[1083] = '.';
+ Header[1082] = 'K';
+ fwrite (Header, 1084, 1, out);
+
+
+ /* put 'where' at track data level - after track list */
+ Where = PW_Start_Address + 762;
/* track/pattern data */
- for ( i=0 ; i<Pat_Pos ; i++ )
+ for (i=0;i<l;i++)
{
-/*fprintf ( info , "\n\n\nPattern %ld :\n" , i );*/
- BZERO ( Whatever , 1024 );
- for ( j=0 ; j<4 ; j++ )
+ BZERO(Pattern,1024);
+ /* which pattern is it now ? */
+ for (j=0;j<Header[950];j++)
{
- Where = PW_Start_Address + 762+(Tracks_Numbers[j][i]*256);
-/*fprintf ( info , "Voice %ld :\n" , j );*/
- for ( k=0 ; k<64 ; k++ )
+ if (Header[952+j] == i)
+ break; /* found */
+ }
+ for (k=0;k<4;k++) /* loop on 4 tracks' refs*/
+ {
+ long d;
+
+ /* loop on notes */
+ for (d=0;d<64;d++)
{
- Whatever[k*16+j*4] = in_data[Where++];
- Whatever[k*16+j*4+1] = in_data[Where++];
- Whatever[k*16+j*4+2] = in_data[Where++];
- Whatever[k*16+j*4+3] = in_data[Where++];
+ /* read one ref value to be fetch in the reference table */
+ long val = Where+(ReadTrkPat[j][k]*256)+(d*4);
+
+ Pattern[k*4+d*16] = in_data[val];
+ Pattern[k*4+d*16+1] = in_data[val + 1];
+ Pattern[k*4+d*16+2] = in_data[val + 2];
+ Pattern[k*4+d*16+3] = in_data[val + 3];
}
}
- fwrite ( Whatever , 1024 , 1 , out );
- /*printf ( "+" );*/
+ fwrite ( Pattern , 1024 , 1 , out );
}
- free ( Whatever );
- /*printf ( "\n" );*/
+ free ( Pattern );
+ free ( Header );
+
/* now, lets put file pointer at the beginning of the sample datas */
- Where = PW_Start_Address + 762 + ((Max+1)*256);
+ Where = PW_Start_Address + 762 + ((Highest_Track+1)*256);
/* sample data */
fwrite ( &in_data[Where] , WholeSampleSize , 1 , out );
* - no more fopen ()
* update : 20100814
* - rewrote depacker (no more useless patterns)
+ * update : 20100815
+ * - removed unused var and ;
*/
void Depack_PP21 ( void )
long Total_Sample_Size=0;
long Where=PW_Start_Address;
FILE *out;
+ /*FILE *info;*/
if ( Save_Status == BAD )
return;
sprintf ( Depacked_OutName , "%ld.mod" , Cpt_Filename-1 );
out = PW_fopen ( Depacked_OutName , "w+b" );
+ /*info = PW_fopen ( "info.txt" , "w+b");*/
Header = (Uchar *)malloc(1084);
Pattern = (Uchar *)malloc(1024);
Header[951] = in_data[Where];
Where += 1;
- // now, where = 0xFA
+ /* now, where = 0xFA*/
for (i=0;i<Header[950];i++)
{
ReadPat[i] = (in_data[Where+i]*256*256*256) +
Highest_Track = ReadTrkPat[i][2];
if (ReadTrkPat[i][3] > Highest_Track)
Highest_Track = ReadTrkPat[i][3];
- /*printf ("%x-%x-%x-%x\n",ReadTrkPat[i][0],ReadTrkPat[i][1],ReadTrkPat[i][2],ReadTrkPat[i][3]);*/
+ /*fprintf (info,"%x-%x-%x-%x (%ld)\n",ReadTrkPat[i][0],ReadTrkPat[i][1],ReadTrkPat[i][2],ReadTrkPat[i][3],ReadPat[i]);*/
}
- /*printf ( "Number of tracks : %d\n" , Highest_Track+1 );*/
+ /*fprintf ( info,"Number of tracks : %d\n\n" , Highest_Track+1 );*/
/* sorting ?*/
k = 0; /* next min */
Header[952+i] = (unsigned char)l;
l++;
}
-
+ if ( l != Header[950] )
+ l -= 1;
+ /*fprintf (info,"number of pattern stored : %ld\n\n",l);*/
+ //fflush (info);
/* write ptk's ID */
Header[1080] = 'M';
/* l is the number of stored patterns */
/* rebuild pattern data now */
whereTableRef = ((Highest_Track + 1)*128) + 4 + Where;
- printf ( "\nwhereTableRef : %ld\n",whereTableRef);
- for (i=0;i<l-1;i++)
+ /*printf ( "\nwhereTableRef : %ld\n",whereTableRef);*/
+ for (i=0;i<l;i++)
{
- long min=50,max=0;
+ /*fprintf (info,"pattern %ld (/%ld)\n",i,l);*/
+ //fflush (info);
BZERO(Pattern,1024);
/* which pattern is it now ? */
for (j=0;j<Header[950];j++)
fflush ( out );
fclose ( out );
+ /*fflush (info);
+ fclose (info);*/
printf ( "done\n" );
return; /* useless ... but */
* - Speed-up and Binary smaller.
* update : 8 dec 2003
* - no more fopen ()
+ * update : 16 aug 2010
+ * - rewrotte depacker for patternlist generation
*/
void Depack_PP30 ( void )
{
- Uchar c1=0x00,c2=0x00;
- short Max=0;
- Uchar Tracks_Numbers[4][128];
- short Tracks_PrePointers[512][64];
- Uchar NOP=0x00; /* number of pattern */
- Uchar *ReferenceTable;
- Uchar *Whatever;
- long i=0,j=0;
+ Uchar *Header, *Pattern;
+ Ulong ReadTrkPat[128][4], ReadPat[128];
+ long Highest_Track = 0;
+ long whereTableRef;
+ long i=0,j=0,k=0,l=0,m=0;
long Total_Sample_Size=0;
- long Where = PW_Start_Address;
+ long Where=PW_Start_Address;
FILE *out;
if ( Save_Status == BAD )
return;
- BZERO ( Tracks_Numbers , 4*128 );
- BZERO ( Tracks_PrePointers , 512*64 );
sprintf ( Depacked_OutName , "%ld.mod" , Cpt_Filename-1 );
out = PW_fopen ( Depacked_OutName , "w+b" );
- /* title */
- Whatever = (Uchar *) malloc (1024);
- BZERO ( Whatever , 1024 );
- fwrite ( Whatever , 20 , 1 , out );
+ Header = (Uchar *)malloc(1084);
+ Pattern = (Uchar *)malloc(1024);
+ BZERO ( Header , 1084 );
+ BZERO ( Pattern , 1024 );
for ( i=0 ; i<31 ; i++ )
{
- /*sample name*/
- fwrite ( Whatever , 22 , 1 , out );
- /* sample siz */
Total_Sample_Size += (((in_data[Where]*256)+in_data[Where+1])*2);
- /* size,fine,vol,lstart,lsize */
- fwrite ( &in_data[Where] , 8 , 1 , out );
+ /* siz,fine,vol,lstart,lsize */
+ Header[42+i*30] = in_data[Where];
+ Header[43+i*30] = in_data[Where+1];
+ Header[44+i*30] = in_data[Where+2];
+ Header[45+i*30] = in_data[Where+3];
+ Header[46+i*30] = in_data[Where+4];
+ Header[47+i*30] = in_data[Where+5];
+ Header[48+i*30] = in_data[Where+6];
+ Header[49+i*30] = in_data[Where+7];
Where += 8;
}
/* pattern table lenght */
- NOP = in_data[Where];
- fwrite ( &NOP , 1 , 1 , out );
+ Header[950] = in_data[Where];
Where += 1;
- /*printf ( "Number of patterns : %d\n" , NOP );*/
+
+ /*printf ( "Number of patterns : %d\n" , Header[950] );*/
/* NoiseTracker restart byte */
- fwrite ( &in_data[Where] , 1 , 1 , out );
+ Header[951] = in_data[Where];
Where += 1;
- Max = 0;
- for ( j=0 ; j<4 ; j++ )
+ // now, where = 0xFA
+ for (i=0;i<Header[950];i++)
{
- for ( i=0 ; i<128 ; i++ )
- {
- Tracks_Numbers[j][i] = in_data[Where];
- Where += 1;
- if ( Tracks_Numbers[j][i] > Max )
- Max = Tracks_Numbers[j][i];
- }
+ ReadPat[i] = (in_data[Where+i]*256*256*256) +
+ (in_data[Where+i+128]*256*256) +
+ (in_data[Where+i+256]*256) +
+ in_data[Where+i+384];
+ ReadTrkPat[i][0] = in_data[Where+i];
+ ReadTrkPat[i][1] = in_data[Where+i+128];
+ ReadTrkPat[i][2] = in_data[Where+i+256];
+ ReadTrkPat[i][3] = in_data[Where+i+384];
+ if (ReadTrkPat[i][0] > Highest_Track)
+ Highest_Track = ReadTrkPat[i][0];
+ if (ReadTrkPat[i][1] > Highest_Track)
+ Highest_Track = ReadTrkPat[i][1];
+ if (ReadTrkPat[i][2] > Highest_Track)
+ Highest_Track = ReadTrkPat[i][2];
+ if (ReadTrkPat[i][3] > Highest_Track)
+ Highest_Track = ReadTrkPat[i][3];
+ /*printf ("%x-%x-%x-%x\n",ReadTrkPat[i][0],ReadTrkPat[i][1],ReadTrkPat[i][2],ReadTrkPat[i][3]);*/
}
+ /*printf ( "Number of tracks : %d\n" , Highest_Track+1 );*/
- /* write pattern table without any optimizing ! */
- for ( c1=0x00 ; c1<NOP ; c1++ )
- fwrite ( &c1 , 1 , 1 , out );
- c2 = 0x00;
- for ( ; c1<128 ; c1++ )
- fwrite ( &c2 , 1 , 1 , out );
-
- Whatever[0] = 'M';
- Whatever[1] = '.';
- Whatever[2] = 'K';
- Whatever[3] = '.';
- fwrite ( Whatever , 4 , 1 , out );
-
+ /* sorting ?*/
+ k = 0; /* next min */
+ l = 0;
- /* PATTERN DATA code starts here */
-
- /*printf ( "Highest track number : %d\n" , Max );*/
- for ( j=0 ; j<=Max ; j++ )
+ /* put the first pattern number */
+ /* could be stored several times */
+ for (j=0; j<Header[950] ; j++)
{
- for ( i=0 ; i<64 ; i++ )
- {
- Tracks_PrePointers[j][i] = ((in_data[Where]*256)+
- in_data[Where+1])/4;
- Where += 2;
- }
+ m = 0x7fffffff; /* min */
+ /*search for min */
+ for (i=0; i<Header[950] ; i++)
+ if ((ReadPat[i]<m) && (ReadPat[i]>k))
+ m = ReadPat[i];
+ /* if k == m then an already existing ref was found */
+ if (k==m)
+ continue;
+ /* m is the next minimum */
+ k = m;
+ for (i=0; i<Header[950] ; i++)
+ if (ReadPat[i] == k)
+ Header[952+i] = (unsigned char)l;
+ l++;
}
+ if ( l != Header[950] )
+ l -= 1;
- /* read "reference table" size */
- j = ((in_data[Where]*256*256*256)+
- (in_data[Where+1]*256*256)+
- (in_data[Where+2]*256)+
- in_data[Where+3]);
- Where += 4;
+ /* write ptk's ID */
+ Header[1080] = 'M';
+ Header[1081] = Header[1083] = '.';
+ Header[1082] = 'K';
+ fwrite (Header, 1084, 1, out);
- /* read "reference Table" */
- ReferenceTable = (Uchar *) malloc ( j );
- for ( i=0 ; i<j ; i++,Where+=1 )
- ReferenceTable[i] = in_data[Where];
- /* NOW, the real shit takes place :) */
- for ( i=0 ; i<NOP ; i++ )
- {
- BZERO ( Whatever , 1024 );
- for ( j=0 ; j<64 ; j++ )
- {
-
- Whatever[j*16] = ReferenceTable[Tracks_PrePointers [Tracks_Numbers [0][i]] [j]*4];
- Whatever[j*16+1] = ReferenceTable[Tracks_PrePointers [Tracks_Numbers [0][i]] [j]*4+1];
- Whatever[j*16+2] = ReferenceTable[Tracks_PrePointers [Tracks_Numbers [0][i]] [j]*4+2];
- Whatever[j*16+3] = ReferenceTable[Tracks_PrePointers [Tracks_Numbers [0][i]] [j]*4+3];
-
- Whatever[j*16+4] = ReferenceTable[Tracks_PrePointers [Tracks_Numbers [1][i]] [j]*4];
- Whatever[j*16+5] = ReferenceTable[Tracks_PrePointers [Tracks_Numbers [1][i]] [j]*4+1];
- Whatever[j*16+6] = ReferenceTable[Tracks_PrePointers [Tracks_Numbers [1][i]] [j]*4+2];
- Whatever[j*16+7] = ReferenceTable[Tracks_PrePointers [Tracks_Numbers [1][i]] [j]*4+3];
-
- Whatever[j*16+8] = ReferenceTable[Tracks_PrePointers [Tracks_Numbers [2][i]] [j]*4];
- Whatever[j*16+9] = ReferenceTable[Tracks_PrePointers [Tracks_Numbers [2][i]] [j]*4+1];
- Whatever[j*16+10]= ReferenceTable[Tracks_PrePointers [Tracks_Numbers [2][i]] [j]*4+2];
- Whatever[j*16+11]= ReferenceTable[Tracks_PrePointers [Tracks_Numbers [2][i]] [j]*4+3];
+ /* put 'where' at track data level - after track list */
+ Where = PW_Start_Address + 762;
- Whatever[j*16+12]= ReferenceTable[Tracks_PrePointers [Tracks_Numbers [3][i]] [j]*4];
- Whatever[j*16+13]= ReferenceTable[Tracks_PrePointers [Tracks_Numbers [3][i]] [j]*4+1];
- Whatever[j*16+14]= ReferenceTable[Tracks_PrePointers [Tracks_Numbers [3][i]] [j]*4+2];
- Whatever[j*16+15]= ReferenceTable[Tracks_PrePointers [Tracks_Numbers [3][i]] [j]*4+3];
+ /* rebuild patterns now */
+ /* l is the number of stored patterns */
+ /* rebuild pattern data now */
+ whereTableRef = ((Highest_Track + 1)*128) + 4 + Where;
+ //printf ( "\nwhereTableRef : %ld\n",whereTableRef);
+ for (i=0;i<l;i++)
+ {
+ BZERO(Pattern,1024);
+ /* which pattern is it now ? */
+ for (j=0;j<Header[950];j++)
+ {
+ if (Header[952+j] == i)
+ break; /* found */
+ }
+ for (k=0;k<4;k++) /* loop on 4 tracks' refs*/
+ {
+ long d;
+
+ /* loop on notes */
+ for (d=0;d<64;d++)
+ {
+ /* read one ref value to be fetch in the reference table */
+ long val = (in_data[Where+(ReadTrkPat[j][k]*128)+(d*2)])*256
+ + in_data[Where+(ReadTrkPat[j][k]*128)+(d*2)+1];
+
+ Pattern[k*4+d*16] = in_data[whereTableRef + val];
+ Pattern[k*4+d*16+1] = in_data[whereTableRef + val + 1];
+ Pattern[k*4+d*16+2] = in_data[whereTableRef + val + 2];
+ Pattern[k*4+d*16+3] = in_data[whereTableRef + val + 3];
+ }
}
- fwrite ( Whatever , 1024 , 1 , out );
+ fwrite ( Pattern , 1024 , 1 , out );
}
- free ( ReferenceTable );
- free ( Whatever );
+ free ( Pattern );
+ free ( Header );
+ /* locate sample start addy - after reference table */
+ j = ((in_data[whereTableRef-4]*256*256*256)+
+ (in_data[whereTableRef-3]*256*256)+
+ (in_data[whereTableRef-2]*256)+
+ in_data[whereTableRef-1]);
+ /*printf ( "\nj:%ld - Where:%ld\n",j,Where );*/
/* sample data */
- /*printf ( "Total sample size : %ld\n" , Total_Sample_Size );*/
- fwrite ( &in_data[Where] , Total_Sample_Size , 1 , out );
+ fwrite ( &in_data[j+whereTableRef] , Total_Sample_Size , 1 , out );
Crap ( " ProPacker v3.0 " , BAD , BAD , out );
}
}
-struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, const TCHAR *model, int all)
+struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, const TCHAR *model, int romflags, bool all)
{
int i, j, ok, out, max;
struct romdata *rd;
continue;
if (model && !_tcsicmp (model, rd->name))
ok = 2;
- if (rd->ver == ver && (rev < 0 || rd->rev == rev)) {
+ if ((ver < 0 || rd->ver == ver) && (rev < 0 || rd->rev == rev)) {
if (subver >= 0) {
if (rd->subver == subver && (subrev < 0 || rd->subrev == subrev) && rd->subver > 0)
ok = 1;
if (model && ok < 2) {
TCHAR *p = rd->model;
ok = 0;
- while (*p) {
+ while (p && *p) {
if (!_tcscmp(rd->model, model)) {
ok = 1;
break;
p = p + _tcslen(p) + 1;
}
}
- if (!model && rd->type != ROMTYPE_KICK)
+ if (romflags && (rd->type & romflags) == 0)
ok = 0;
if (ok) {
if (all) {
}
}
} else {
- io_error = CDERR_NotSpecified;
+ io_error = IOERR_NotSpecified;
}
}
break;
put_long (io_data + 8, diskpos);
io_actual = 12;
} else {
- io_error = CDERR_InvalidState;
+ io_error = IOERR_InvalidState;
}
} else {
io_error = IOERR_BADADDRESS;