Changes for 1 global capture directory
Support for capturing raw midi Support for capturing raw opl Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1864
This commit is contained in:
parent
b1cebeed4e
commit
dc6e126a71
2 changed files with 151 additions and 39 deletions
|
@ -19,16 +19,23 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "inout.h"
|
||||
#include "mixer.h"
|
||||
#include "pic.h"
|
||||
#include "hardware.h"
|
||||
#include "setup.h"
|
||||
#include "mapper.h"
|
||||
#include "mem.h"
|
||||
|
||||
/*
|
||||
Thanks to vdmsound for nice simple way to implement this
|
||||
*/
|
||||
# define logerror
|
||||
|
||||
#define logerror
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* Disable recurring warnings */
|
||||
|
@ -75,12 +82,24 @@ namespace THEOPL3 {
|
|||
#define OPL2_INTERNAL_FREQ 3600000 // The OPL2 operates at 3.6MHz
|
||||
#define OPL3_INTERNAL_FREQ 14400000 // The OPL3 operates at 14.4MHz
|
||||
|
||||
#define RAW_SIZE 1024
|
||||
static struct {
|
||||
bool active;
|
||||
OPL_Mode mode;
|
||||
MIXER_Channel * chan;
|
||||
Bit32u last_used;
|
||||
Bit16s mixbuf[2][128];
|
||||
struct {
|
||||
FILE * handle;
|
||||
Bit32u start;
|
||||
Bit32u last;
|
||||
Bit8u index;
|
||||
Bit8u buffer[RAW_SIZE+8];
|
||||
Bit8u regs[2][256];
|
||||
Bit32u used;
|
||||
Bit32u done;
|
||||
Bit8u cmd[2];
|
||||
} raw;
|
||||
} opl;
|
||||
|
||||
static void OPL_CallBack(Bit8u *stream, Bit32u len) {
|
||||
|
@ -104,7 +123,6 @@ static void OPL_CallBack(Bit8u *stream, Bit32u len) {
|
|||
((Bit16u *)stream)[i*2+1]=opl.mixbuf[1][i];
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
if ((PIC_Ticks-opl.last_used)>5000) {
|
||||
MIXER_Enable(opl.chan,false);
|
||||
|
@ -125,27 +143,147 @@ static Bitu OPL_Read(Bitu port,Bitu iolen) {
|
|||
return 0xff;
|
||||
}
|
||||
|
||||
static void OPL_RawAdd(Bitu index,Bitu val);
|
||||
void OPL_Write(Bitu port,Bitu val,Bitu iolen) {
|
||||
opl.last_used=PIC_Ticks;
|
||||
if (!opl.active) {
|
||||
opl.active=true;
|
||||
MIXER_Enable(opl.chan,true);
|
||||
}
|
||||
Bitu addr=port & 3;
|
||||
if (!addr) adlib_commandreg=val;
|
||||
port&=3;
|
||||
if (port&1) {
|
||||
Bitu index=port>>1;
|
||||
opl.raw.regs[index][opl.raw.cmd[index]]=val;
|
||||
if (opl.raw.handle) OPL_RawAdd(index,val);
|
||||
} else opl.raw.cmd[port>>1]=val;
|
||||
if (!port) adlib_commandreg=val;
|
||||
switch (opl.mode) {
|
||||
case OPL_opl2:
|
||||
OPL2::YM3812Write(0,addr,val);
|
||||
OPL2::YM3812Write(0,port,val);
|
||||
break;
|
||||
case OPL_opl3:
|
||||
THEOPL3::YMF262Write(0,addr,val);
|
||||
THEOPL3::YMF262Write(0,port,val);
|
||||
break;
|
||||
case OPL_dualopl2:
|
||||
OPL2::YM3812Write(addr>>1,addr,val);
|
||||
OPL2::YM3812Write(port>>1,port,val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static Bit8u dro_header[]={
|
||||
'D','B','R','A', /* Bit32u ID */
|
||||
'W','O','P','L', /* Bit32u ID */
|
||||
0x0,0x0,0x0,0x0, /* Bit32u total milliseconds */
|
||||
0x0,0x0,0x0,0x0, /* Bit32u total data */
|
||||
0x0, /* Type 0=opl2,1=opl3,2=dual-opl2 */
|
||||
};
|
||||
/* Commands
|
||||
0x00 Bit8u, millisecond delay+1
|
||||
0x01 Bit16u, millisecond delay+1
|
||||
0x02 none, Use the low index/data pair
|
||||
0x03 none, Use the high index/data pair
|
||||
0xxx Bit8u, send command and data to current index/data pair
|
||||
*/
|
||||
|
||||
static void OPL_RawEmptyBuffer(void) {
|
||||
fwrite(opl.raw.buffer,1,opl.raw.used,opl.raw.handle);
|
||||
opl.raw.done+=opl.raw.used;
|
||||
opl.raw.used=0;
|
||||
}
|
||||
|
||||
#define ADDBUF(_VAL_) opl.raw.buffer[opl.raw.used++]=_VAL_;
|
||||
static void OPL_RawAdd(Bitu index,Bitu val) {
|
||||
/* Check if we have yet to start */
|
||||
if (!opl.raw.start) {
|
||||
Bitu i;
|
||||
opl.raw.last=PIC_Ticks;
|
||||
opl.raw.start=PIC_Ticks;
|
||||
/* Check the registers to add */
|
||||
for (i=4;i<256;i++) {
|
||||
if (!opl.raw.regs[0][i]) continue;
|
||||
if ((i &0xe0)==0xb0) continue;
|
||||
ADDBUF((Bit8u)i);
|
||||
ADDBUF(opl.raw.regs[0][i]);
|
||||
}
|
||||
bool donesecond=false;
|
||||
for (i=4;i<256;i++) {
|
||||
if (!opl.raw.regs[0][i]) continue;
|
||||
if ((i&0xe0)==0xb0) continue;
|
||||
if (!donesecond) {
|
||||
donesecond=true;
|
||||
ADDBUF(0x3);
|
||||
}
|
||||
ADDBUF((Bit8u)i);
|
||||
ADDBUF(opl.raw.regs[0][i]);
|
||||
}
|
||||
if (donesecond) ADDBUF(0x2);
|
||||
}
|
||||
/* Check how much time has passed, Allow an extra 5 milliseconds? */
|
||||
if (PIC_Ticks>(opl.raw.last+5)) {
|
||||
Bitu passed=PIC_Ticks-opl.raw.last;
|
||||
opl.raw.last=PIC_Ticks;
|
||||
while (passed) {
|
||||
passed-=1;
|
||||
if (passed<256) {
|
||||
ADDBUF(0x00); //8bit delay
|
||||
ADDBUF((Bit8u)passed); //8bit delay
|
||||
passed=0;
|
||||
} else if (passed<0x10000) {
|
||||
ADDBUF(0x01); //16bit delay
|
||||
ADDBUF((Bit8u)(passed & 0xff)); //lo-byte
|
||||
ADDBUF((Bit8u)(passed >> 8)); //hi-byte
|
||||
passed=0;
|
||||
} else {
|
||||
ADDBUF(0x01); //16bit delay
|
||||
ADDBUF(0xff); //lo-byte
|
||||
ADDBUF(0xff); //hi-byte
|
||||
passed-=0xffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Check if we're still sending to the correct index */
|
||||
if (opl.raw.index != index) {
|
||||
opl.raw.index=index;
|
||||
ADDBUF(opl.raw.index ? 0x3 : 0x2);
|
||||
}
|
||||
ADDBUF(opl.raw.cmd[opl.raw.index]);
|
||||
ADDBUF(val);
|
||||
if (opl.raw.used>=RAW_SIZE) OPL_RawEmptyBuffer();
|
||||
}
|
||||
|
||||
static void OPL_SaveRawEvent(void) {
|
||||
/* Check for previously opened wave file */
|
||||
if (opl.raw.handle) {
|
||||
LOG_MSG("Stopping Raw OPL capturing.");
|
||||
OPL_RawEmptyBuffer();
|
||||
/* Fill in the header with useful information */
|
||||
host_writed(&dro_header[0x08],opl.raw.last-opl.raw.start);
|
||||
host_writed(&dro_header[0x0c],opl.raw.done);
|
||||
switch (opl.mode) {
|
||||
case OPL_opl2:host_writeb(&dro_header[0x10],0x0);break;
|
||||
case OPL_opl3:host_writeb(&dro_header[0x10],0x1);break;
|
||||
case OPL_dualopl2:host_writeb(&dro_header[0x10],0x2);break;
|
||||
}
|
||||
fseek(opl.raw.handle,0,0);
|
||||
fwrite(dro_header,1,sizeof(dro_header),opl.raw.handle);
|
||||
fclose(opl.raw.handle);
|
||||
opl.raw.handle=0;
|
||||
return;
|
||||
}
|
||||
opl.raw.handle=OpenCaptureFile("Raw Opl",".dro");
|
||||
opl.raw.index=0;
|
||||
opl.raw.used=0;
|
||||
opl.raw.done=0;
|
||||
opl.raw.start=0;
|
||||
opl.raw.last=0;
|
||||
memset(opl.raw.buffer,0,sizeof(opl.raw.buffer));
|
||||
fwrite(dro_header,1,sizeof(dro_header),opl.raw.handle);
|
||||
}
|
||||
|
||||
static void OPL_Stop(Section* sec) {
|
||||
if (opl.raw.handle) OPL_SaveRawEvent();
|
||||
}
|
||||
|
||||
void OPL_Init(Section* sec,Bitu base,OPL_Mode oplmode,Bitu rate) {
|
||||
Section_prop * section=static_cast<Section_prop *>(sec);
|
||||
if (OPL2::YM3812Init(2,OPL2_INTERNAL_FREQ,rate)) {
|
||||
|
@ -170,9 +308,11 @@ void OPL_Init(Section* sec,Bitu base,OPL_Mode oplmode,Bitu rate) {
|
|||
opl.active=false;
|
||||
opl.last_used=0;
|
||||
opl.mode=oplmode;
|
||||
|
||||
memset(opl.raw.regs,0,sizeof(opl.raw.regs));
|
||||
opl.chan=MIXER_AddChannel(OPL_CallBack,rate,"FM");
|
||||
MIXER_SetMode(opl.chan,(opl.mode>OPL_opl2) ? MIXER_16STEREO : MIXER_16MONO);
|
||||
MIXER_Enable(opl.chan,false);
|
||||
MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL");
|
||||
sec->AddDestroyFunction(&OPL_Stop);
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue