//#ifdef __MINGW32__ //typedef struct vswprintf {} swprintf; //#endif #include #include #include #include #if !defined(_MSC_VER) && !defined(__WATCOMC__) #define PACKED_STRUCT __attribute__((packed)) #else #define PACKED_STRUCT #endif #if defined(_MSC_VER) || defined(__WATCOMC__) #pragma pack(push,1) #endif struct BNK1_header { char maj_vers, min_vers; char signature[6]; // "ADLIB-" unsigned short ins_used, ins_entries; unsigned name_list, inst_data; } PACKED_STRUCT; struct BNK1_record { unsigned short index; unsigned char used; char name[9]; } PACKED_STRUCT; struct OPL2_op { unsigned char key_scale_lvl; unsigned char freq_mult; unsigned char feedback; unsigned char attack; unsigned char sustain_lvl; unsigned char sustain_sound; unsigned char decay; unsigned char release; unsigned char out_lvl; unsigned char amp_vib; unsigned char pitch_vib; unsigned char env_scaling; unsigned char connection; } PACKED_STRUCT; struct BNK1_instrument { unsigned char sound_mode; unsigned char voice_num; OPL2_op ops[2]; unsigned char waveforms[2]; } PACKED_STRUCT; // conventional Ad Lib instrument maker bankfile patch struct BNK2_header { char signature[28]; // "Accomp. Bank, (C) AdLib Inc" unsigned short file_ver; char filler[10]; unsigned short ins_entries, ins_used; int lostSpace; } PACKED_STRUCT; struct BNK2_record { char O3_sig[3]; char key[12]; char used; int attrib, dataOffset; unsigned short blockSize, allocBSize; } PACKED_STRUCT; struct OPL3_op { unsigned char AVEKMMMM, KKLLLLLL; unsigned char AAAADDDD, SSSSRRRR; unsigned char DxxxxWWW, xxxxxxxx; } PACKED_STRUCT; struct BNK2_instrument { OPL3_op ops[4]; unsigned char C4xxxFFFC; unsigned char xxP24NNN; unsigned char TTTTTTTT; unsigned char xxxxxxxx; } PACKED_STRUCT; // Ad Lib Gold instrument maker bankfile patch #if defined(_MSC_VER) || defined(__WATCOMC__) #pragma pack(pop) #endif static void LoadBNK1(const std::vector& data) { const BNK1_header& bnk1 = *(const BNK1_header*) &data[0]; const BNK1_record* names = (const BNK1_record*) &data[ bnk1.name_list ]; const BNK1_instrument* ins = (const BNK1_instrument*) &data[ bnk1.inst_data ]; std::printf("BNK1 version: %d.%d\n", bnk1.maj_vers, bnk1.min_vers); for(unsigned a=0; a& data) { const BNK2_header& bnk2 = *(const BNK2_header*) &data[0]; const BNK2_record* names = (const BNK2_record*) &data[ sizeof(bnk2) ]; std::printf("BNK2 version: %d, lost space %d\n", bnk2.file_ver, bnk2.lostSpace); for(unsigned a=0; a data(ftell(fp)); std::rewind(fp); size_t got = std::fread(&data[0], 1, data.size(), fp); std::fclose(fp); if(got == 0) { std::fprintf(stderr, "ERROR: Can't read %s file!", fn); return; } const BNK1_header& bnk1 = *(const BNK1_header*) &data[0]; const BNK2_header& bnk2 = *(const BNK2_header*) &data[0]; if(std::memcmp(bnk1.signature, "ADLIB-", 6) == 0) LoadBNK1(data); else if(std::memcmp(bnk2.signature, "Accomp. Bank, (C) AdLib Inc", 28) == 0) LoadBNK2(data); else std::fprintf(stderr, "%s: Unknown format\n", fn); } int main(int argc, const char* const* argv) { if(argc < 2) { std::printf("Usage: \n" " %s filename.bnk\n" "\n", argv[0]); return 1; } LoadBNK(argv[1]); }