Example #1
0
int COGLColorCombiner4::ParseDecodedMux2Units()
{
    OGLExtCombinerSaveType res;
    for( int k=0; k<8; k++ )
        res.units[k].tex = -1;

    res.numOfUnits = 2;

    for( int i=0; i<res.numOfUnits*2; i++ ) // Set combiner for each texture unit
    {
        // For each texture unit, set both RGB and Alpha channel
        // Keep in mind that the m_pDecodeMux has been reformatted and simplified very well

        OGLExtCombinerType &unit = res.units[i/2];
        OGLExt1CombType &comb = unit.Combs[i%2];

        CombinerFormatType type = m_pDecodedMux->splitType[i];
        N64CombinerType &m = m_pDecodedMux->m_n64Combiners[i];

        comb.arg0 = comb.arg1 = comb.arg2 = MUX_0;

        switch( type )
        {
        case CM_FMT_TYPE_NOT_USED:
            comb.arg0 = MUX_COMBINED;
            unit.ops[i%2] = GL_REPLACE;
            break;
        case CM_FMT_TYPE_D:                 // = A
            comb.arg0 = m.d;
            unit.ops[i%2] = GL_REPLACE;
            break;
        default:
            comb.arg0 = m.a;
            comb.arg1 = m.b;
            comb.arg2 = m.c;
            unit.ops[i%2] = GL_INTERPOLATE_ARB;
            break;
        }
    }

    if( m_pDecodedMux->splitType[2] == CM_FMT_TYPE_NOT_USED && m_pDecodedMux->splitType[3] == CM_FMT_TYPE_NOT_USED && !m_bTex1Enabled )
    {
        res.numOfUnits = 1;
    }

    res.units[0].tex = 0;
    res.units[1].tex = 1;

    return SaveParsedResult(res);
}
int COGLColorCombiner2::ParseDecodedMux()
{
    //return COGLColorCombiner4::ParseDecodedMux();

    int generalCombinerIndex = CGeneralCombiner::FindCompiledMux();
    if( generalCombinerIndex < 0 )      // Can not found
    {
        generalCombinerIndex = CGeneralCombiner::ParseDecodedMux();
    }

    GeneralCombinerInfo &generalRes = m_vCompiledCombinerStages[generalCombinerIndex];
    OGLExtCombinerSaveType res;

    // Convert generalRes to OGLExtCombinerSaveType
    for( int unitNo=0; unitNo<generalRes.nStages; unitNo++ )
    {
        OGLExtCombinerType &unit = res.units[unitNo];
        //OGLExt1CombType &colorComb = unit.Combs[0];
        //OGLExt1CombType &alphaComb = unit.Combs[1];

        unit.rgbArg0 = (uint8)generalRes.stages[unitNo].colorOp.Arg1;
        unit.rgbArg1 = (uint8)generalRes.stages[unitNo].colorOp.Arg2;
        unit.rgbArg2 = (uint8)generalRes.stages[unitNo].colorOp.Arg0;
        unit.alphaArg0 = (uint8)generalRes.stages[unitNo].alphaOp.Arg1;
        unit.alphaArg1 = (uint8)generalRes.stages[unitNo].alphaOp.Arg2;
        unit.alphaArg2 = (uint8)generalRes.stages[unitNo].alphaOp.Arg0;

        unit.rgbOp = GeneralToGLMaps[generalRes.stages[unitNo].colorOp.op];
        if( unit.rgbOp == GL_MODULATE_ADD_ATI && !m_bTxtOpMulAdd )
        {
            if( (unit.rgbArg0&MUX_MASK) == (unit.rgbArg2&MUX_MASK) && (unit.rgbArg0&MUX_COMPLEMENT) )
            {
//                unit.rgbOp = GL_ADD;
                unit.rgbArg0 &= ~MUX_COMPLEMENT;
            }
            else
            {
//                unit.rgbOp = GL_MODULATE;
            }
        }
        unit.alphaOp = GeneralToGLMaps[generalRes.stages[unitNo].alphaOp.op];
        if( unit.alphaOp == GL_MODULATE_ADD_ATI && !m_bTxtOpMulAdd )
        {
            if( (unit.alphaArg0&MUX_MASK) == (unit.alphaArg2&MUX_MASK) && (unit.alphaArg0&MUX_COMPLEMENT) )
            {
//                unit.alphaOp = GL_ADD;
                unit.alphaArg0 &= ~MUX_COMPLEMENT;
            }
            else
            {
//                unit.alphaOp = GL_MODULATE;
            }
        }

        unit.tex = generalRes.stages[unitNo].dwTexture;
        unit.textureIsUsed = generalRes.stages[unitNo].bTextureUsed;
    }

    res.numOfUnits = generalRes.nStages;
    res.constantColor = generalRes.TFactor;
    return SaveParsedResult(res);
}
int COGLColorCombiner4::ParseDecodedMux()
{
#define nextUnit()  {unitNo++;}
#ifndef USE_GLES
    if( m_maxTexUnits<3) 
        return  ParseDecodedMux2Units();

    OGLExtCombinerSaveType res;
    for( int k=0; k<8; k++ )
        res.units[k].tex = -1;
    
    COGLDecodedMux &mux = *(COGLDecodedMux*)m_pDecodedMux;

    int unitNos[2];
    for( int rgbalpha = 0; rgbalpha<2; rgbalpha++ )
    {
        unitNos[rgbalpha] = 0;
        for( int cycle = 0; cycle<2; cycle++ )
        {
            int &unitNo = unitNos[rgbalpha];
            OGLExtCombinerType &unit = res.units[unitNo];
            OGLExt1CombType &comb = unit.Combs[rgbalpha];
            CombinerFormatType type = m_pDecodedMux->splitType[cycle*2+rgbalpha];
            N64CombinerType &m = m_pDecodedMux->m_n64Combiners[cycle*2+rgbalpha];
            comb.arg0 = comb.arg1 = comb.arg2 = CM_IGNORE_BYTE;

            switch( type )
            {
            case CM_FMT_TYPE_NOT_USED:
                comb.arg0 = MUX_COMBINED;
                unit.ops[rgbalpha] = GL_REPLACE;
                nextUnit();
                break;
            case CM_FMT_TYPE_D:                 // = A
                comb.arg0 = m.d;
                unit.ops[rgbalpha] = GL_REPLACE;
                nextUnit();
                break;
            case CM_FMT_TYPE_A_ADD_D:           // = A+D
                comb.arg0 = m.a;
                comb.arg1 = m.d;
                unit.ops[rgbalpha] = GL_ADD;
                nextUnit();
                break;
            case CM_FMT_TYPE_A_SUB_B:           // = A-B
                comb.arg0 = m.a;
                comb.arg1 = m.b;
                unit.ops[rgbalpha] = GL_SUBTRACT;
                nextUnit();
                break;
            case CM_FMT_TYPE_A_MOD_C:           // = A*C
                comb.arg0 = m.a;
                comb.arg1 = m.c;
                unit.ops[rgbalpha] = GL_MODULATE;
                nextUnit();
                break;
            case CM_FMT_TYPE_A_MOD_C_ADD_D:     // = A*C+D
                if( m_bSupportModAdd_ATI )
                {
                    comb.arg0 = m.a;
                    comb.arg2 = m.c;
                    comb.arg1 = m.d;
                    unit.ops[rgbalpha] = GL_MODULATE_ADD_ATI;
                    nextUnit();
                }
                else
                {
                    if( unitNo < m_maxTexUnits-1 )
                    {
                        comb.arg0 = m.a;
                        comb.arg1 = m.c;
                        unit.ops[rgbalpha] = GL_MODULATE;
                        nextUnit();
                        res.units[unitNo].Combs[rgbalpha].arg0 = MUX_COMBINED;
                        res.units[unitNo].Combs[rgbalpha].arg1 = m.d;
                        res.units[unitNo].ops[rgbalpha] = GL_ADD;
                        nextUnit();
                    }
                    else
                    {
                        comb.arg0 = m.a;
                        comb.arg1 = m.c;
                        comb.arg2 = m.d;
                        unit.ops[rgbalpha] = GL_INTERPOLATE;
                        nextUnit();
                    }
                }
                break;
            case CM_FMT_TYPE_A_LERP_B_C:        // = (A-B)*C+B
                comb.arg0 = m.a;
                comb.arg1 = m.b;
                comb.arg2 = m.c;
                unit.ops[rgbalpha] = GL_INTERPOLATE;
                nextUnit();
                break;
            case CM_FMT_TYPE_A_SUB_B_ADD_D:     // = A-B+D
                if( unitNo < m_maxTexUnits-1 )
                {
                    comb.arg0 = m.a;
                    comb.arg1 = m.b;
                    unit.ops[rgbalpha] = GL_SUBTRACT;
                    nextUnit();
                    res.units[unitNo].Combs[rgbalpha].arg0 = MUX_COMBINED;
                    res.units[unitNo].Combs[rgbalpha].arg1 = m.d;
                    res.units[unitNo].ops[rgbalpha] = GL_ADD;
                    nextUnit();
                }
                else
                {
                    comb.arg0 = m.a;
                    comb.arg1 = m.c;
                    comb.arg2 = m.d;
                    unit.ops[rgbalpha] = GL_INTERPOLATE;
                    nextUnit();
                }
                break;
            case CM_FMT_TYPE_A_SUB_B_MOD_C:     // = (A-B)*C
                if( unitNo < m_maxTexUnits-1 )
                {
                    comb.arg0 = m.a;
                    comb.arg1 = m.b;
                    unit.ops[rgbalpha] = GL_SUBTRACT;
                    nextUnit();
                    res.units[unitNo].Combs[rgbalpha].arg0 = MUX_COMBINED;
                    res.units[unitNo].Combs[rgbalpha].arg1 = m.c;
                    res.units[unitNo].ops[rgbalpha] = GL_MODULATE;
                    nextUnit();
                }
                else
                {
                    comb.arg0 = m.a;
                    comb.arg1 = m.c;
                    comb.arg2 = m.d;
                    unit.ops[rgbalpha] = GL_INTERPOLATE;
                    nextUnit();
                }
                break;
            case CM_FMT_TYPE_A_B_C_D:           // = (A-B)*C+D
            default:
                if( unitNo < m_maxTexUnits-1 )
                {
                    comb.arg0 = m.a;
                    comb.arg1 = m.b;
                    unit.ops[rgbalpha] = GL_SUBTRACT;
                    nextUnit();
                    if( m_bSupportModAdd_ATI )
                    {
                        res.units[unitNo].Combs[rgbalpha].arg0 = MUX_COMBINED;
                        res.units[unitNo].Combs[rgbalpha].arg2 = m.c;
                        res.units[unitNo].Combs[rgbalpha].arg1 = m.d;
                        res.units[unitNo].ops[rgbalpha] = GL_MODULATE_ADD_ATI;
                        nextUnit();
                    }
                    else
                    {
                        res.units[unitNo].Combs[rgbalpha].arg0 = m.a;
                        res.units[unitNo].Combs[rgbalpha].arg1 = m.b;
                        res.units[unitNo].Combs[rgbalpha].arg2 = m.c;
                        res.units[unitNo].ops[rgbalpha] = GL_INTERPOLATE;
                        nextUnit();
                    }
                }
                else
                {
                    comb.arg0 = m.a;
                    comb.arg1 = m.c;
                    comb.arg2 = m.d;
                    unit.ops[rgbalpha] = GL_INTERPOLATE;
                    nextUnit();
                }
                break;
            }
        }
    }
        
    res.numOfUnits = std::min(m_maxTexUnits, std::max(unitNos[0],unitNos[1]));

    if( unitNos[0]>m_maxTexUnits || unitNos[1]>m_maxTexUnits ) 
    {
        TRACE0("Unit overflows");
    }

    for( int j=0; j<2; j++ )
    {
        if( unitNos[j]<res.numOfUnits )
        {
            for( int i=unitNos[j]; i<res.numOfUnits; i++ )
            {
                res.units[i].Combs[j].arg0 = MUX_COMBINED;
                res.units[i].ops[j] = GL_REPLACE;
            }
        }
    }

    res.units[0].tex = 0;
    res.units[1].tex = 1;

    res.primIsUsed = mux.isUsed(MUX_PRIM);
    res.envIsUsed = mux.isUsed(MUX_ENV);
    res.lodFracIsUsed = mux.isUsed(MUX_LODFRAC) || mux.isUsed(MUX_PRIMLODFRAC);

    return SaveParsedResult(res);

#else
    return 0;
#endif
}