//--------------------------------------------------------------------------- // ebxa.cpp //--------------------------------------------------------------------------- #include #define BLOCKSIZE (128) #define BLOCKS_PER_SECTOR (18) #pragma argsused int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { return 1; } //--------------------------------------------------------------------------- extern "C" __declspec(dllexport) void __stdcall ebxa(char* file, int start, int len); extern "C" __declspec(dllexport) int __stdcall wave_length(int start, int len); extern "C" __declspec(dllexport) bool __stdcall ebxa2wave(char* file, char* pvWaveData, int start, int len); HANDLE file_open(char* file); int file_seek(HANDLE hFile, unsigned long offset); int file_read(HANDLE hFile, unsigned char* buffer, int size); void XADecode(char* &wavep,char* sbuf,int& y,int& z); // play EB-XA sound data void __stdcall ebxa(char* file, int start, int len) { char* pvWaveData = new char[wave_length(start, len)]; if (ebxa2wave(file, pvWaveData, start, len)) PlaySound((LPCSTR)pvWaveData, NULL, SND_MEMORY | SND_SYNC); delete [] pvWaveData; } // necessary memory length for wave data int __stdcall wave_length(int start, int length) { return 8 * 28 * 2 * 18 * ((length + 15) / 16) + 44; } // convert EBXA data to wave data bool __stdcall ebxa2wave(char* file, char* pvWaveData, int start, int len) { int end = start + len - 1; // length of wave data int length = 8 * 28 * 2 * 18 * (((end - start) >> 4) + 1); HANDLE sound = file_open(file); if (sound == NULL) return false; unsigned char buf[BLOCKSIZE]; // Write WAV Header // RIFF chunk ID strncpy(pvWaveData, "RIFF", 4); // chunk size @Data + Header Length *((long *)&pvWaveData[4]) = length + 36; // WAVE header strncpy(pvWaveData + 8, "WAVE", 4); // fmt chunk ID strncpy(pvWaveData + 12, "fmt ", 4); // chunk size 16 bytes *((long *)&pvWaveData[16]) = 16; // format IDF 1= real PCM *((short *)&pvWaveData[20]) = 1; // channels 1= monoral *((short *)&pvWaveData[22]) = 1; // sampling rate *((long *)&pvWaveData[24]) = 18900; // transfer rate // bytesPerSec = sampling_rate * unit_size *((long *)&pvWaveData[28]) = 18900 * 2; // unit size (bytes) // (channels * bits_per_1_sample) / 8 *((short *)&pvWaveData[32]) = 2; // bits per 1 sample // 8 or 16 bits *((short *)&pvWaveData[34]) = 16; // data chunk ID strncpy(pvWaveData + 36, "data", 4); // size of wave data *((long *)&pvWaveData[40]) = length; char* wavep = pvWaveData + 44; // decode EB-XA data int y = 0, z = 0; for (int lba = start; lba <= end ; lba += 16) { file_seek(sound, lba * 0x930 + 0x44); for (int i = 0; i < BLOCKS_PER_SECTOR; i++) { file_read(sound, buf, BLOCKSIZE); XADecode(wavep, buf, y, z); } } // close sound file CloseHandle(sound); return true; } HANDLE file_open(char* file) { SetErrorMode(1); HANDLE hFileIndex = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); SetErrorMode(0); if (hFileIndex == (HANDLE)-1) return NULL; return hFileIndex; } int file_seek(HANDLE hFile, unsigned long offset) { DWORD dwPointer = SetFilePointer(hFile, offset, NULL, FILE_BEGIN); if (dwPointer == 0xFFFFFFFF) { return -1; } return 0; } int file_read(HANDLE hFile, unsigned char* buffer, int size) { unsigned long nBytesRead; ReadFile(hFile, buffer, size, &nBytesRead, NULL) ; return nBytesRead; } // decode EB-XA data void XADecode(char* &wavep,char* sbuf,int& y,int& z){ const int k0[4]={0,0xf0,0x1cc,0x188}; const int k1[4]={0,0,-0xd0,-0xdc}; int x; unsigned char* ubuf=reinterpret_cast(sbuf); for(int i=0;i<8;i++){ int r=12-(ubuf[i+4]&15); int f=(ubuf[i+4]>>4)&15; for(int j=0;j<28;j++){ x=ubuf[i/2+j*4+16]; if (i&1) x>>=4; x&=15; if (x>=8) x-=16; x<<=r; x+=(y*k0[f]+z*k1[f])/256; if (x<-0x8000) x=-0x8000; if (x>0x7fff) x=0x7fff; *wavep++ = x & 255; *wavep++ = ((0xff00 & x) >> 8)&255; z=y; y=x; } } }