예제 #1
0
파일: xgmcom.c 프로젝트: luciano2000/SGDK
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);
}
예제 #2
0
파일: xgmcom.c 프로젝트: luciano2000/SGDK
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);
}
예제 #3
0
파일: xgmcom.c 프로젝트: luciano2000/SGDK
XGMCommand* XGMCommand_createEndCommand()
{
    unsigned char* data = malloc(1);

    data[0] = XGM_END;

    return XGMCommand_create(data, 1);
}
예제 #4
0
파일: xgmcom.c 프로젝트: luciano2000/SGDK
XGMCommand* XGMCommand_createFrameCommand()
{
    unsigned char* data = malloc(1);

    data[0] = XGM_FRAME;

    return XGMCommand_create(data, 1);
}
예제 #5
0
파일: xgmcom.c 프로젝트: luciano2000/SGDK
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);
}
예제 #6
0
파일: xgmcom.c 프로젝트: feli7254/SGDK
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);
}
예제 #7
0
파일: xgmcom.c 프로젝트: feli7254/SGDK
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);
}
예제 #8
0
파일: xgmcom.c 프로젝트: luciano2000/SGDK
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);
}
예제 #9
0
파일: xgmcom.c 프로젝트: luciano2000/SGDK
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);
}
예제 #10
0
파일: xgmcom.c 프로젝트: feli7254/SGDK
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);
}
예제 #11
0
파일: xgmcom.c 프로젝트: luciano2000/SGDK
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);
}