static XGMCommand* XGMCommand_createYMPort1Command(LList** pcommands) { LList* curCom = *pcommands; const int size = min(16, getSizeLList(curCom)); unsigned char* data = malloc((size * 2) + 1); int i, off; data[0] = XGM_YM2612_PORT1 | (size - 1); off = 1; for (i = 0; i < size; i++) { VGMCommand* command = curCom->element; data[off++] = VGMCommand_getYM2612Register(command); data[off++] = VGMCommand_getYM2612Value(command); curCom = curCom->next; } // update list pointer to remove elements we have done *pcommands = curCom; return XGMCommand_create(data, (size * 2) + 1); }
XGMCommand* XGMCommand_createFromData(unsigned char* data) { unsigned char command = *data; unsigned char size = command & 0xF; // default int comSize = 1; switch(command & 0xF0) { case XGM_PSG: case XGM_YM2612_REGKEY: comSize += size + 1; break; case XGM_YM2612_PORT0: case XGM_YM2612_PORT1: comSize += (size + 1) * 2; break; case XGM_PCM: comSize = 2; break; case 0x70: // LOOP if (size == 0xE) comSize = 4; break; } return XGMCommand_create(data, comSize); }
XGMCommand* XGMCommand_createEndCommand() { unsigned char* data = malloc(1); data[0] = XGM_END; return XGMCommand_create(data, 1); }
XGMCommand* XGMCommand_createFrameCommand() { unsigned char* data = malloc(1); data[0] = XGM_FRAME; return XGMCommand_create(data, 1); }
XGMCommand* XGMCommand_createLoopCommand(int offset) { unsigned char* data = malloc(4); data[0] = XGM_LOOP; data[1] = offset >> 0; data[2] = offset >> 8; data[3] = offset >> 16; return XGMCommand_create(data, 4); }
static XGMCommand* XGMCommand_createPSGCommand(List* commands, int* offset) { const int size = min(16, commands->size - *offset); unsigned char* data = malloc(size + 1); int i, off; data[0] = XGM_PSG | (size - 1); off = 1; for (i = 0; i < size; i++) data[off++] = VGMCommand_getPSGValue(getFromList(commands, i + *offset)); // remove elements we have done *offset += size; return XGMCommand_create(data, size + 1); }
XGMCommand* XGMCommand_createYMKeyCommand(List* commands, int* offset, int max) { const int size = min(max, commands->size - *offset); unsigned char* data = malloc(size + 1); int i, off; data[0] = XGM_YM2612_REGKEY | (size - 1); off = 1; for (i = 0; i < size; i++) data[off++] = VGMCommand_getYM2612Value(getFromList(commands, i + *offset)); // remove elements we have done *offset += size; return XGMCommand_create(data, size + 1); }
static XGMCommand* XGMCommand_createPSGCommand(LList** pcommands) { LList* curCom = *pcommands; const int size = min(16, getSizeLList(curCom)); unsigned char* data = malloc(size + 1); int i, off; data[0] = XGM_PSG | (size - 1); off = 1; for (i = 0; i < size; i++) { data[off++] = VGMCommand_getPSGValue(curCom->element); curCom = curCom->next; } // update list pointer to remove elements we have done *pcommands = curCom; return XGMCommand_create(data, size + 1); }
XGMCommand* XGMCommand_createYMKeyCommand(LList** pcommands, int max) { LList* curCom = *pcommands; const int size = min(max, getSizeLList(curCom)); unsigned char* data = malloc(size + 1); int i, off; data[0] = XGM_YM2612_REGKEY | (size - 1); off = 1; for (i = 0; i < size; i++) { data[off++] = VGMCommand_getYM2612Value(curCom->element); curCom = curCom->next; } // update list pointer to remove elements we have done *pcommands = curCom; return XGMCommand_create(data, size + 1); }
static XGMCommand* XGMCommand_createYMPort1Command(List* commands, int* offset) { const int size = min(16, commands->size - *offset); unsigned char* data = malloc((size * 2) + 1); int i, off; data[0] = XGM_YM2612_PORT1 | (size - 1); off = 1; for (i = 0; i < size; i++) { VGMCommand* command = getFromList(commands, i + *offset); data[off++] = VGMCommand_getYM2612Register(command); data[off++] = VGMCommand_getYM2612Value(command); } // remove elements we have done *offset += size; return XGMCommand_create(data, (size * 2) + 1); }
static XGMCommand* XGMCommand_createPCMCommand(XGM* xgm, VGM* vgm, VGMCommand* command, int channel) { unsigned char* data = malloc(2); XGMSample* xgmSample; unsigned char prio; data[0] = XGM_PCM; prio = 0; if (VGMCommand_isStreamStartLong(command)) { int address; int size; Sample* vgmSample; address = VGMCommand_getStreamSampleAddress(command); size = VGMCommand_getStreamSampleSize(command); // vgmSample = VGM_getSample(vgm, address, size); vgmSample = VGM_getSample(vgm, address); // use stream id as priority prio = 3 - (VGMCommand_getStreamId(command) & 0x3); xgmSample = XGM_getSampleByAddress(xgm, address); if (vgmSample != NULL) { double len; int lenInFrame; len = VGMCommand_getStreamSampleSize(command); lenInFrame = ceil(len / ((double) vgmSample->rate / (double) vgm->rate)); } else if (!silent) printf("Warning: can't find original VGM sample for VGM command at offset %6X\n", command->offset); } else if (VGMCommand_isStreamStart(command)) { // use stream id as priority prio = 3 - (VGMCommand_getStreamId(command) & 0x3); xgmSample = XGM_getSampleByIndex(xgm, VGMCommand_getStreamBlockId(command) + 1); if (xgmSample == NULL) xgmSample = XGM_getSampleByIndex(xgm, prio + 1); } else if (VGMCommand_isStreamStop(command)) { // use stream id as priority prio = 3 - (VGMCommand_getStreamId(command) & 0x3); // stop command data[1] = 0; return XGMCommand_create(data, 2); } else { // assume stop command by default data[1] = 0; return XGMCommand_create(data, 2); } // no sample found --> use empty sample if (xgmSample == NULL) { if (!silent) printf("Warning: no corresponding sample found for VGM command at offset %6X in XGM\n", command->offset); data[1] = 0; } else data[1] = xgmSample->index; // channel == -1 --> we use inverse of priority for channel if (channel == -1) data[0] |= 3 - prio; else data[0] |= (channel & 0x3); // set prio data[0] |= prio << 2; return XGMCommand_create(data, 2); }