Hi,

Woo-hoo! The list appears to be working again! :-)
I don't have the slightest clue as to when it ceased to function, though;
please re-submit any mail that may have been lost before I found out that
things were broken once again.
SFAI.

---------- Forwarded message ----------
Date: Sun, 15 Oct 2000 23:12:21 +0200 (MET DST)
From: Christoph Reichenbach <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
Subject: Repost: OPL/2 patches and software sequencer [was: FreeSCI Sound
    System (fwd)]

Hi,

(Now that's a subject line...)

I sent this earlier today, but it appears to have been lost. I changed
some settings in the mailing list's config file, so, maybe it'll work
now.
SFAI.

---------- Forwarded message ----------
Date: Sun, 15 Oct 2000 10:08:30 +0200 (MET DST)
From: Christoph Reichenbach <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
Subject: OPL/2 patches and software sequencer [was: FreeSCI Sound System (fwd)]

Hi,

Philip Hassey recently contacted me, offering some code to read out the
OPL/2 patch resource (resource.003), and pointing out that MAME
(http://www.mame.net) comes with a software OPL/2 emulator (fm.h,
fmopl.[hc]). This should make it possible to add an Emulator for
Adlib-style music eventually.

Here's his code:
[snip]
//Here's code to load the instruments:
int load_sierra_ins(midPlayer *p)
{
    long i,j,k,l;
    int tins=0;
    FILE *stream;
    unsigned char ins[28];
    char pfilename[256];

    sprintf(pfilename,p->fname);
    j=0;
    for (i=strlen(pfilename)-1; i>=0; i--)
        if (pfilename[i]=='/' ||
            pfilename[i]=='\\') {j=i+1; i=-1;}
            sprintf(pfilename+j+3,"patch.003");

    stream=fopen(pfilename,"rb");
    fgetc(stream);
    fgetc(stream);

    for (i=0; i<2; i++)
        {
        for (k=0; k<48; k++)
            {
            l=i*48+k;
            for (j=0; j<28; j++)
                ins[j]=fgetc(stream);

            p->myinsbank[l][0]=
                (ins[9]*0x80) + (ins[10]*0x40) +
                (ins[5]*0x20) + (ins[11]*0x10) +
                ins[1];   //1=ins5
            p->myinsbank[l][1]=
                (ins[22]*0x80) + (ins[23]*0x40) +
                (ins[18]*0x20) + (ins[24]*0x10) +
                ins[14];  //1=ins18

            p->myinsbank[l][2]=(ins[0]<<6)+ins[8];
            p->myinsbank[l][3]=(ins[13]<<6)+ins[21];

            p->myinsbank[l][4]=(ins[3]<<4)+ins[6];
            p->myinsbank[l][5]=(ins[16]<<4)+ins[19];
            p->myinsbank[l][6]=(ins[4]<<4)+ins[7];
            p->myinsbank[l][7]=(ins[17]<<4)+ins[20];

            p->myinsbank[l][8]=ins[26];
            p->myinsbank[l][9]=ins[27];

            p->myinsbank[l][10]=((ins[2]<<1))+(1-(ins[12]&1));

            tins++;
            }
        fgetc(stream);fgetc(stream);
        }
    fclose(stream);
    return(tins);
}

//If anything is unclear as to what is going on up there, just ask.
//
//Here's some basic AdLib code:
//You'll note that SIERRA_STYLE changes a few things about how
// the adlib is used.  So you can change the code so it always
// assumes SIERRA STYLE to be true for your purposes.

static void midi_write_adlib(unsigned int r, unsigned char v, midPlayer *p)
{
    adlibwrite(p->OPL,r,v);
    p->adlib_data[r]=v;
}

unsigned char adlib_opadd[] = {
         0x00  ,0x01 ,0x02  ,0x08  ,0x09  ,0x0A  ,0x10 ,0x11  ,0x12 };
int ops[] = {
        0x20,0x20,0x40,0x40,0x60,0x60,0x80,0x80,0xe0,0xe0,0xc0 };

static void midi_fm_instrument(int voice, unsigned char *inst, midPlayer *p)
{
    if ((p->adlib_style&SIERRA_STYLE)!=0)
        midi_write_adlib(0xbd,0,p);  //just gotta make sure this happens..
                                      //'cause who knows when it'll be
                                      //reset otherwise.


    midi_write_adlib(0x20+adlib_opadd[voice],inst[0],p);
    midi_write_adlib(0x23+adlib_opadd[voice],inst[1],p);

    if ((p->adlib_style&LUCAS_STYLE)!=0)
        {
        midi_write_adlib(0x43+adlib_opadd[voice],0x3f,p);
        if ((inst[10] & 1)==0)
            midi_write_adlib(0x40+adlib_opadd[voice],inst[2],p);
            else
            midi_write_adlib(0x40+adlib_opadd[voice],0x3f,p);
        }
        else
        {
        if ((p->adlib_style&SIERRA_STYLE)!=0)
            {
            midi_write_adlib(0x40+adlib_opadd[voice],inst[2],p);
            midi_write_adlib(0x43+adlib_opadd[voice],inst[3],p);
            }
            else
            {
            midi_write_adlib(0x40+adlib_opadd[voice],inst[2],p);
            if ((inst[10] & 1)==0)
                midi_write_adlib(0x43+adlib_opadd[voice],inst[3],p);
                else
                midi_write_adlib(0x43+adlib_opadd[voice],0,p);
            }
        }

    midi_write_adlib(0x60+adlib_opadd[voice],inst[4],p);
    midi_write_adlib(0x63+adlib_opadd[voice],inst[5],p);
    midi_write_adlib(0x80+adlib_opadd[voice],inst[6],p);
    midi_write_adlib(0x83+adlib_opadd[voice],inst[7],p);
    midi_write_adlib(0xe0+adlib_opadd[voice],inst[8],p);
    midi_write_adlib(0xe3+adlib_opadd[voice],inst[9],p);

    midi_write_adlib(0xc0+voice,inst[10],p);
}

static void midi_fm_volume(int voice, int volume, midPlayer *p)
{
    int vol;

    if ((p->adlib_style&SIERRA_STYLE)==0)  //sierra likes it loud!
    {
    vol=volume>>2;

    if ((p->adlib_style&LUCAS_STYLE)!=0)
        {
        if ((p->adlib_data[0xc0+voice]&1)==1)
            midi_write_adlib(0x40+adlib_opadd[voice], (unsigned 
char)((63-vol) |
            (p->adlib_data[0x40+adlib_opadd[voice]]&0xc0)),p);
        midi_write_adlib(0x43+adlib_opadd[voice], (unsigned char)((63-vol) |
            (p->adlib_data[0x43+adlib_opadd[voice]]&0xc0)),p);
        }
        else
        {
        if ((p->adlib_data[0xc0+voice]&1)==1)
            midi_write_adlib(0x40+adlib_opadd[voice], (unsigned 
char)((63-vol) |
            (p->adlib_data[0x40+adlib_opadd[voice]]&0xc0)),p);
        midi_write_adlib(0x43+adlib_opadd[voice], (unsigned char)((63-vol) |
           (p->adlib_data[0x43+adlib_opadd[voice]]&0xc0)),p);
        }
    }
}


int fnums[] = {
0x16b,0x181,0x198,0x1b0,0x1ca,0x1e5,0x202,0x220,0x241,0x263,0x287,0x2ae
                  };

int sierra_fnums[] = {
0xB6,0xC1,0xCD,0xD9,0xE6,0xF3,0x102,0x111,0x122,0x133,0x145,0x158
};


static void midi_fm_playnote(int voice, int note, int volume, midPlayer *p)
{
    int freq=fnums[note%12];
    int oct=note/12;
        int c;

    if ((p->adlib_style&SIERRA_STYLE)!=0)
        {
        oct++;
        freq=sierra_fnums[note%12];
        }

    midi_fm_volume(voice,volume,p);
    midi_write_adlib(0xa0+voice,(unsigned char)(freq&0xff),p);

        c=((freq&0x300) >> 8)+(oct<<2) + (1<<5);
    midi_write_adlib(0xb0+voice,(unsigned char)c,p);
}

static void midi_fm_endnote(int voice, midPlayer *p)
{
    //midi_fm_volume(voice,0);
    //midi_write_adlib(0xb0+voice,0);

    midi_write_adlib(0xb0+voice,(unsigned 
char)(p->adlib_data[0xb0+voice]&(255-32)),p);
}

static void midi_fm_reset(midPlayer *p)
{
    int i;
    for (i=0; i<256; i++)
        midi_write_adlib(i,0,p);

    midi_write_adlib(0x01, 0x20,p);
    midi_write_adlib(0xBD,0xc0,p);
}

[snip]

I haven't looked at it very thoroughly yet, but it appears to contain
sufficient information to get this to work. (Note that, if we want to use
the code, the LUCAS_STYLE stuff would have to be removed, findResource()
would have to be used instead of the various file operations, and comments
would have to be changed from // to /* */ to support older compilers.
There may be less obvious stuff that needs changing, though.)

llap,
 Christoph




Reply via email to