FITD/FitdLib/music.cpp

1305 lines
24 KiB
C++

#include "common.h"
bool g_gameUseCDA = false;
int musicVolume = 0x7F;
unsigned int musicChrono;
typedef int(*musicDrvFunctionType)(void * ptr);
#ifndef AITD_UE4
struct FM_OPL* virtualOpl;
#endif
char OPLinitialized = 0;
#define OPL_INTERNAL_FREQ 3579545
void callMusicUpdate(void);
struct channelTable2Element
{
u16 index;
struct channelTable2Element *var2;
u16 var4;
u8* dataPtr;
u8* commandPtr;
s16 varE;
u16 var10;
u8 var12;
u16 var13;
u16 var15;
u8 var17;
u16 var18;
u8 var1A;
u8 var1B;
u8 var1C;
u8 var1D;
u8 var1E;
};
typedef struct channelTable2Element channelTable2Element;
typedef void(*musicCommandType)(channelTable2Element* entry, int param,u8* ptr);
struct channelTableElement
{
u16 var0;
u16 var2;
u8 var4;
u8 var5;
u8 var6;
u8 var7;
u16 var8;
};
typedef struct channelTableElement channelTableElement;
channelTableElement channelDataTable[11] =
{
{0xFFFF, 0x40, 0xFF, 0xFF, 0xFF, 0x9C, 0xFFFF},
{0xFFFF, 0x40, 0xFF, 0xFF, 0xFF, 0x9C, 0xFFFF},
{0xFFFF, 0x40, 0xFF, 0xFF, 0xFF, 0x9C, 0xFFFF},
{0xFFFF, 0x40, 0xFF, 0xFF, 0xFF, 0x9C, 0xFFFF},
{0xFFFF, 0x40, 0xFF, 0xFF, 0xFF, 0x9C, 0xFFFF},
{0xFFFF, 0x40, 0xFF, 0xFF, 0xFF, 0x9C, 0xFFFF},
{0xFFFF, 0x40, 0xFF, 0xFF, 0xFF, 0x9C, 0xFFFF},
{0xFFFF, 0x40, 0xFF, 0xFF, 0xFF, 0x9C, 0xFFFF},
{0xFFFF, 0x40, 0xFF, 0xFF, 0xFF, 0x9C, 0xFFFF},
{0xFFFF, 0x40, 0xFF, 0xFF, 0xFF, 0x9C, 0xFFFF},
{0xFFFF, 0x40, 0xFF, 0xFF, 0xFF, 0x9C, 0xFFFF}
};
extern channelTable2Element channelTable3[11];
extern channelTable2Element channelTable2[11];
channelTable2Element channelTable3[11] =
{
{ 0, &channelTable2[0],0x8040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 1, &channelTable2[1],0x8040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 2, &channelTable2[2],0x8040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 3, &channelTable2[3],0x8040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 4, &channelTable2[4],0x8040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 5, &channelTable2[5],0x8040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 6, &channelTable2[6],0x8040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 7, &channelTable2[7],0x8040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 8, &channelTable2[8],0x8040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 9, &channelTable2[9],0x8040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{10,&channelTable2[10],0x8040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0}
};
channelTable2Element channelTable2[11] =
{
{ 0, &channelTable3[0],0x0040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 1, &channelTable3[1],0x0040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 2, &channelTable3[2],0x0040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 3, &channelTable3[3],0x0040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 4, &channelTable3[4],0x0040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 5, &channelTable3[5],0x0040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 6, &channelTable3[6],0x0040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 7, &channelTable3[7],0x0040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 8, &channelTable3[8],0x0040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{ 9, &channelTable3[9],0x0040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
{10,&channelTable3[10],0x0040,NULL,NULL,0,0,0,0,0,0,0,0x7F,1,1,0x7F,0},
};
unsigned char regBDConf = 0xC0;
unsigned char channelTableMelodic[] =
{
0x00,
0x03,
0x01,
0x04,
0x02,
0x05,
0x08,
0x0B,
0x09,
0x0C,
0x0A,
0x0D,
0x10,
0x13,
0x11,
0x14,
0x12,
0x15,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF
};
unsigned char channelTableRythme[] =
{
0x00,
0x03,
0x01,
0x04,
0x02,
0x05,
0x08,
0x0B,
0x09,
0x0C,
0x0A,
0x0D,
0x10,
0x13,
0x14,
0xFF,
0x12,
0xFF,
0x15,
0xFF,
0x11,
0xFF
};
unsigned char* channelTable;
// global table is 300 entry long
u16 globTableEntry[300] = {
0x157,
0x158,
0x159,
0x15A,
0x15A,
0x15B,
0x15C,
0x15D,
0x15E,
0x15F,
0x15F,
0x160,
0x161,
0x162,
0x163,
0x164,
0x164,
0x165,
0x166,
0x167,
0x168,
0x168,
0x169,
0x16A,
0x16B,
0x16C,
0x16D,
0x16D,
0x16E,
0x16F,
0x170,
0x171,
0x172,
0x173,
0x174,
0x174,
0x175,
0x176,
0x177,
0x178,
0x179,
0x17A,
0x17B,
0x17B,
0x17C,
0x17D,
0x17E,
0x17F,
0x180,
0x181,
0x181,
0x183,
0x183,
0x184,
0x185,
0x186,
0x187,
0x188,
0x189,
0x18A,
0x18B,
0x18C,
0x18D,
0x18E,
0x18E,
0x18F,
0x190,
0x191,
0x192,
0x193,
0x194,
0x195,
0x196,
0x197,
0x198,
0x198,
0x19A,
0x19A,
0x19B,
0x19C,
0x19D,
0x19F,
0x19F,
0x1A0,
0x1A1,
0x1A2,
0x1A3,
0x1A4,
0x1A5,
0x1A6,
0x1A7,
0x1A8,
0x1A9,
0x1AA,
0x1AB,
0x1AC,
0x1AD,
0x1AE,
0x1AF,
0x1B0,
0x1B1,
0x1B2,
0x1B3,
0x1B4,
0x1B5,
0x1B6,
0x1B7,
0x1B8,
0x1B9,
0x1BA,
0x1BB,
0x1BC,
0x1BD,
0x1BF,
0x1C0,
0x1C1,
0x1C2,
0x1C3,
0x1C4,
0x1C5,
0x1C6,
0x1C7,
0x1C8,
0x1C9,
0x1CA,
0x1CB,
0x1CC,
0x1CD,
0x1CE,
0x1CF,
0x1D0,
0x1D2,
0x1D3,
0x1D4,
0x1D5,
0x1D6,
0x1D7,
0x1D8,
0x1D9,
0x1DA,
0x1DB,
0x1DD,
0x1DE,
0x1DF,
0x1E0,
0x1E1,
0x1E2,
0x1E3,
0x1E4,
0x1E5,
0x1E6,
0x1E8,
0x1E9,
0x1EA,
0x1EB,
0x1EC,
0x1ED,
0x1EF,
0x1F0,
0x1F1,
0x1F2,
0x1F3,
0x1F4,
0x1F6,
0x1F7,
0x1F8,
0x1F9,
0x1FA,
0x1FB,
0x1FD,
0x1FE,
0x1FF,
0x200,
0x201,
0x202,
0x203,
0x205,
0x206,
0x207,
0x208,
0x20A,
0x20B,
0x20C,
0x20D,
0x20F,
0x210,
0x211,
0x212,
0x214,
0x215,
0x216,
0x217,
0x219,
0x21A,
0x21B,
0x21C,
0x21D,
0x21F,
0x220,
0x221,
0x222,
0x224,
0x225,
0x226,
0x227,
0x229,
0x22A,
0x22C,
0x22D,
0x22E,
0x22F,
0x231,
0x232,
0x234,
0x235,
0x236,
0x237,
0x239,
0x23A,
0x23B,
0x23C,
0x23E,
0x23F,
0x241,
0x242,
0x243,
0x245,
0x246,
0x247,
0x248,
0x24A,
0x24B,
0x24D,
0x24E,
0x250,
0x251,
0x252,
0x254,
0x255,
0x257,
0x258,
0x259,
0x25B,
0x25C,
0x25E,
0x25F,
0x260,
0x262,
0x263,
0x264,
0x266,
0x267,
0x269,
0x26A,
0x26B,
0x26D,
0x26E,
0x270,
0x271,
0x273,
0x274,
0x276,
0x277,
0x279,
0x27A,
0x27C,
0x27D,
0x27F,
0x280,
0x282,
0x283,
0x285,
0x286,
0x288,
0x289,
0x28A,
0x28C,
0x28D,
0x28F,
0x291,
0x292,
0x294,
0x295,
0x297,
0x299,
0x29A,
0x29C,
0x29D,
0x29F,
0x2A0,
0x2A2,
0x2A3,
0x2A5,
0x2A7,
0x2A8,
0x2AA,
0x2AB,
0x2AD,
0x2AF,
0x2B0,
};
u16* globTable[13] =
{
&globTableEntry[0],
&globTableEntry[25],
&globTableEntry[50],
&globTableEntry[75],
&globTableEntry[100],
&globTableEntry[125],
&globTableEntry[150],
&globTableEntry[175],
&globTableEntry[200],
&globTableEntry[225],
&globTableEntry[250],
&globTableEntry[275],
};
unsigned char musicParam1 = 0;
u8* currentMusicPtr = NULL;
u8* currentMusicPtr2 = NULL;
u8* currentMusicPtr3 = NULL;
u8 generalVolume = 0;
void sendAdlib(int regIdx, int value)
{
YM3812Write(0,0,regIdx);
YM3812Write(0,1,value);
}
#define musicSync 1500
int musicTimer = 0;
int nextUpdateTimer = musicSync;
int musicUpdate(void *udata, uint8 *stream, int len)
{
if(OPLinitialized)
{
int fillStatus = 0;
while(fillStatus < len)
{
int timeBeforNextUpdate = nextUpdateTimer - musicTimer;
if(timeBeforNextUpdate > (len - fillStatus))
{
timeBeforNextUpdate = len-fillStatus;
}
if(timeBeforNextUpdate) // generate
{
YM3812UpdateOne(0,(int16*)(stream+fillStatus),(timeBeforNextUpdate)/2);
fillStatus+=timeBeforNextUpdate;
musicTimer+=timeBeforNextUpdate;
}
if(musicTimer == nextUpdateTimer)
{
callMusicUpdate();
nextUpdateTimer += musicSync;
}
}
}
return 0;
}
void createDefaultChannel(int index)
{
channelDataTable[index].var5 = 0xFF;
channelDataTable[index].var4 = 0xFF;
channelDataTable[index].var2 = 0x40;
channelDataTable[index].var0 = 0xFFFF;
channelDataTable[index].var7 = 0x9C;
channelDataTable[index].var8 = 0xFFFF;
}
void resetChannelFrequency(int channelIdx)
{
sendAdlib(0xA0+channelIdx,0);
sendAdlib(0xB0+channelIdx,0);
}
void setupChannelFrequency(int channelIdx, int cl, int dx,int bp)
{
u16* di;
u16 frequency;
u8 frequencyLow;
u8 frequencyHigh;
u8 blockNumber;
if(!(bp&0x8000))
{
sendAdlib(0xB0+channelIdx, 0);
}
di = globTable[cl&0xF];
if(bp & 0x80)
{
// assert(0);
}
if(cl & 0x80)
{
dx = 0x40;
}
frequency = di[bp&0xFF];
frequencyLow = frequency&0xFF;
sendAdlib(0xA0+channelIdx,frequencyLow);
blockNumber = (cl&0x70)>>2;
frequencyHigh = ((frequency>>8)&0x3)|blockNumber;
if(!(dx&0x40))
{
frequencyHigh |= 0x20; // set key on
}
sendAdlib(0xB0+channelIdx,frequencyHigh);
}
int musicStart(void* dummy)
{
int i;
sendAdlib(1,0x20);
sendAdlib(8,0);
sendAdlib(0xBD,regBDConf);
for(i=0;i<18;i++)
{
sendAdlib(0x60+channelTableMelodic[i],0xFF);
sendAdlib(0x80+channelTableMelodic[i],0xFF);
}
for(i=0;i<9;i++)
{
resetChannelFrequency(i);
}
for(i=0;i<11;i++)
{
createDefaultChannel(i);
}
if(!musicParam1)
{
resetChannelFrequency(6);
setupChannelFrequency(6,0,0x40,0);
resetChannelFrequency(7);
setupChannelFrequency(7,7,0x40,0);
resetChannelFrequency(8);
setupChannelFrequency(8,0,0x40,0);
}
return 0;
}
int musicLoad(void* ptr)
{
int i;
u8 flag1;
u8* musicPtr = (u8*)ptr;
channelTable = channelTableMelodic;
flag1 = musicPtr[0x3C] & 0xC0;
musicParam1 = musicPtr[0x3D];
if(!musicParam1)
{
flag1 |= 0x20;
channelTable = channelTableRythme;
}
regBDConf = flag1;
for(i=0;i<11;i++)
{
unsigned long int offset;
offset = READ_LE_U32(musicPtr + i*4 + 8);
if(offset)
{
channelTable2[i].dataPtr = musicPtr + offset;
}
else
{
channelTable2[i].dataPtr = NULL;
}
channelTable2[i].var4 |= 0x40;
}
currentMusicPtr = musicPtr + READ_LE_U16(musicPtr + 0x34);
return 0;
}
int initialialize(void* dummy)
{
int i;
//OPLBuildTables(FMOPL_ENV_BITS_HQ, FMOPL_EG_ENT_HQ);
YM3812Init(1,OPL_INTERNAL_FREQ,44100);
/* virtualOpl = OPLCreate(OPL_TYPE_YM3812, OPL_INTERNAL_FREQ, 44100);
if(!virtualOpl)
return 0; */
for(i=0;i<11;i++)
{
channelTable2[i].var4 |= 0x20;
channelTable2[i].var2->var4 |= 0x20;
createDefaultChannel(i);
}
musicStart(NULL);
OPLinitialized = 1;
return 0;
}
int getSignature(void* dummy)
{
return 0;
}
void commandNop(channelTable2Element* entry, int param,u8* ptr)
{
}
void command0(channelTable2Element* entry, int param,u8* ptr)
{
entry->var4 |= 2;
if(entry->var4 & 0x20)
{
return;
}
entry->var4 |= 0x40;
if(!(entry->var4 & 0x8000))
{
return;
}
entry->var2->var4 &= 0xFFFB;
}
void command1(channelTable2Element* entry, int param,u8* ptr)
{
u16 ax;
ax = READ_LE_U16(ptr-1);
entry->var10 = entry->varE = ax+entry->var13;
entry->commandPtr ++;
}
void command2(channelTable2Element* entry, int param,u8* ptr)
{
entry->var18++;
entry->var15 = param;
}
void command3(channelTable2Element* entry, int param,u8* ptr)
{
entry->var12 = param;
}
void command4(channelTable2Element* entry, int param,u8* ptr)
{
entry->var1E = param;
}
void command5(channelTable2Element* entry, int param,u8* ptr)
{
entry->var17 = param;
}
void command6(channelTable2Element* entry, int param,u8* ptr)
{
assert(0);
}
musicCommandType musicCommandTable[10] =
{
command0,
command1,
command2,
command3,
command4,
command5,
command6,
commandNop,
commandNop,
commandNop,
};
void executeMusicCommand(channelTable2Element* entry)
{
u16 opcode;
if(entry->var4&0x40)
return;
if(entry->var4&0x02) // start channel
{
entry->commandPtr = entry->dataPtr;
entry->var4 &= 0xFFFD;
entry->var18 = 0;
}
else
{
if(entry->var1A != entry->var1D)
{
assert(0);
}
entry->varE--; // voice delay
if(entry->varE<=0)
{
entry->varE = entry->var10;
}
else
{
return;
}
}
do
{
opcode = READ_LE_U16(entry->commandPtr);
entry->commandPtr+=2;
ASSERT(musicCommandTable[opcode&0x7F]);
ASSERT((opcode&0x7F)<=10);
musicCommandTable[opcode&0x7F](entry,opcode>>8,entry->commandPtr);
}while(!(opcode&0x80));
}
u8 smallTable[] = { 0x10, 8, 4, 2, 1 };
void applyDirectFrequency(int index, int param1, int param2, int param3)
{
if(musicParam1)
{
setupChannelFrequency(index,param1,param2,param3);
return;
}
else
{
int ah;
if(index<6)
{
setupChannelFrequency(index,param1,param2,param3);
return;
}
if(index==6)
{
setupChannelFrequency(index,param1,0x40,param3);
}
else
if(index==8 && !(param1&0x80))
{
int indexBackup = index;
int param1Backup = param1;
setupChannelFrequency(8,param1,0x40,param3);
{
int al = param1&0x70;
index = 7;
param1 &= 0xF;
param1+=7;
if(param1 >= 0xC)
{
param1 -= 0xC;
if(al != 0x70)
al += 0x10;
}
setupChannelFrequency( index, param1, 0x40,param3);
}
param1 = param1Backup;
index = indexBackup;
}
ah = (~(smallTable[index-6])) & regBDConf;
sendAdlib(0xBD,ah);
if(!(param2 & 0x40) && !(param1 & 0x80))
{
ah |= smallTable[index-6];
sendAdlib(0xBD,ah);
}
regBDConf = ah;
}
}
unsigned char smallData2[] =
{
0,
1,
2,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
3 ,
4 ,
5 ,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
6 ,
7 ,
8 ,
0xFF,
0xFF,
0xFF,
};
void configChannel(u8 value, u8* data)
{
if(smallData2[value] != 0xFF)
{
sendAdlib(0xC0 + smallData2[value], data[2]);
}
sendAdlib(0x60 + value, data[4]); // Attack Rate Decay Rate
sendAdlib(0x80 + value, data[5]); // Sustain Level Release Rate
sendAdlib(0x20 + value, data[1]); // Tremolo Vibrato Sustain KSR Frequency Multiplication Factor
sendAdlib(0xE0 + value, data[3]); // Waveform Select
}
void changeOuputLevel(u8 value, u8* data,int bp)
{
int keyScaleLevel;
int outputLevel;
if(value == 0xFF)
return;
data++;
outputLevel = (*data)&0x3F;
outputLevel = 0x3F - ((((outputLevel*bp)*2) + 0x7F)/0xFE);
ASSERT((outputLevel & 0x3F) == outputLevel);
keyScaleLevel = data[0]&0xC0;
sendAdlib(0x40+value,(data[0]&0xC0) | (outputLevel&0x3F));
}
void applyMusicCommandToOPL(channelTable2Element* element2, channelTableElement* element)
{
char al;
u16 dx;
u16 bp;
u8 operator1;
u8 operator2;
if((element2->var4 & 0x40) != element->var2)
{
element->var2 = element2->var4 & 0x40;
if(element2->var4 & 0x40)
{
applyDirectFrequency(element2->index,element2->var15 | 0x80, 0x40, element2->var17);
createDefaultChannel(element2->index);
return;
}
}
if(element2->var4 & 0x40)
return;
if((element->var8 & 1) || (element->var8 != (element2->var4&0x8000)))
{
element->var8 = element2->var4&0x8000;
element->var5 = 0xFF;
element->var4 = 0xFF;
element->var0 = 0xFFFF;
element->var7 = 0x9C;
}
operator1 = channelTable[element2->index*2];
operator2 = channelTable[(element2->index*2)+1];
if(operator1 == 0xFF && operator2 == 0xFF) // do we have an operator ?
return;
if(element2->var12 != element->var4) // change channel main config
{
element->var4 = element2->var12;
configChannel(operator1,(currentMusicPtr2+0xD*element2->var12)+1);
if(operator2 != 0xFF)
{
configChannel(operator2,(currentMusicPtr2+0xD*element2->var12)+7);
}
element->var5 = 0xFF;
}
// Ouput level handling
al = element2->var1D - element2->var1E;
if(al < 0)
al = 0;
if(element->var5 != al)
{
int dx;
element->var5 = al;
dx = element2->var1D;
if(operator2==0xFF)
{
dx = element->var5;
}
changeOuputLevel(operator1,currentMusicPtr2+0xD*element2->var12,dx);
if(operator2 != 0xFF)
{
changeOuputLevel(operator2,(currentMusicPtr2+0xD*element2->var12)+6,element->var5);
}
}
////
bp = dx = element2->var17;
if(element2->var17 != element->var7)
{
element->var7 = element2->var17;
if(element2->var15 == element->var0)
{
bp |= 0x8000;
}
}
else
{
if(element2->var15 == element->var0)
return;
}
element->var0 = element2->var15 = element2->var15 | 0x8000;
applyDirectFrequency(element2->index,element->var0&0xFF,element2->var4,bp);
}
int update(void* dummy)
{
int i;
channelTable2Element* si;
if(generalVolume & 0xFF)
{
return 0;
}
for(i=0;i<11;i++)
{
currentMusicPtr2 = currentMusicPtr;
executeMusicCommand(&channelTable2[i]);
si = &channelTable2[i];
if(channelTable2[i].var4 & 4)
{
currentMusicPtr2 = currentMusicPtr3;
si = channelTable2[i].var2;
executeMusicCommand(channelTable2[i].var2);
}
applyMusicCommandToOPL(si,&channelDataTable[i]);
}
return 0;
}
int musicFade(void * param)
{
int i;
int cx;
int si;
int dx;
int bp;
cx = ((int*)param)[0];
si = ((int*)param)[1];
dx = ((int*)param)[2];
bp = si;
si = -1;
if(!bp)
bp = 0x7FF;
for(i=0;i<11;i++)
{
// if((bp&i))
{
if(channelTable2[i].dataPtr)
{
if(dx & 0x100)
{
assert(0);
}
if(dx & 0x40)
{
if(!(channelTable2[i].var4&0x40))
channelTable2[i].var4|=0x40;
}
if(dx & 0x80) // start all
{
channelTable2[i].var4 = 0x40;
cx &= 0x7F;
channelTable2[i].var1D = cx;
channelTable2[i].var1A = cx;
channelTable2[i].var1E = 0;
createDefaultChannel(channelTable2[i].index);
channelTable2[i].var4 = 2;
}
if(dx & 0x20)
{
assert(0);
}
if(dx & 0x2000)
{
assert(0);
}
if(dx & 0x8000)
{
channelTable2[i].var1A = cx;
}
if(dx & 0x1000)
{
assert(0);
}
if(dx & 0x10) // still running ?
{
if(!(dx & 0x2000))
{
if(!(channelTable2[i].var4 & 0x40))
{
if(si < channelTable2[i].var18)
si = channelTable2[i].var18;
}
}
else
{
if(channelTable2[i].var1D != cx)
{
si = 0;
}
}
}
}
}
}
return si;
}
musicDrvFunctionType musicDrvFunc[14]=
{
update,
initialialize,
musicStart,
musicLoad,
NULL,
musicFade,
NULL,
NULL,
getSignature,
NULL,
NULL,
NULL,
NULL,
NULL,
};
int callMusicDrv(int commandArg,void* ptr)
{
if(!musicDrvFunc[commandArg])
{
assert(0);
}
return musicDrvFunc[commandArg](ptr);
}
int initMusicDriver(void)
{
callMusicDrv(1,NULL);
return callMusicDrv(8,NULL);
}
void loadMusic(int param, char* musicPtr)
{
callMusicDrv(3,musicPtr);
callMusicDrv(2,NULL);
}
int fadeParam[3];
int fadeMusic(int param1, int param2, int param3)
{
fadeParam[0] = param1;
fadeParam[1] = param2;
fadeParam[2] = param3;
return callMusicDrv(5,&fadeParam);
}
void playMusic(int musicNumber)
{
if(currentMusic == musicNumber)
return;
currentMusic = musicNumber;
int trackNumber = musicNumber;
if(g_gameId == AITD2)
{
trackNumber = AITD2MusicToTrackMapping[musicNumber];
}
if(osystem_playTrack(trackNumber))
return;
// if(musicEnabled)
{
//if(currentMusic != musicNumber)
{
char* musicPtr;
currentMusic = musicNumber;
if(musicNumber>=0)
{
fadeMusic(0,0,0x40);
musicPtr = HQR_Get(listMus,musicNumber);
if(musicPtr)
{
loadMusic(0,musicPtr);
fadeMusic(musicVolume,0,0x80);
#ifndef TARGET_OS_IPHONE
osystem_playAdlib();
#endif
}
}
}
}
}
int updateLoop = 0;
int oldTimer = 0;
void callMusicUpdate(void)
{
if(OPLinitialized)
{
callMusicDrv(0,NULL);
}
}
void destroyMusicDriver(void)
{
YM3812Shutdown();
}