~ubuntu-branches/ubuntu/precise/mupen64plus/precise

« back to all changes in this revision

Viewing changes to rice_video/Combiner.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Sven Eckelmann
  • Date: 2009-09-08 22:17:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090908221700-yela0ckgc1xwiqtn
Tags: upstream-1.5+dfsg1
ImportĀ upstreamĀ versionĀ 1.5+dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (C) 2002 Rice1964
 
3
 
 
4
This program is free software; you can redistribute it and/or
 
5
modify it under the terms of the GNU General Public License
 
6
as published by the Free Software Foundation; either version 2
 
7
of the License, or (at your option) any later version.
 
8
 
 
9
This program is distributed in the hope that it will be useful,
 
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
GNU General Public License for more details.
 
13
 
 
14
You should have received a copy of the GNU General Public License
 
15
along with this program; if not, write to the Free Software
 
16
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
17
 
 
18
*/
 
19
 
 
20
#include "stdafx.h"
 
21
 
 
22
//static BOOL g_bHiliteRGBAHack = FALSE;
 
23
 
 
24
//const char * sc_colcombtypes32[32] =
 
25
//{
 
26
//  "Combined    ", "Texel0      ",
 
27
//  "Texel1      ", "Primitive   ", 
 
28
//  "Shade       ", "Environment ",
 
29
//  "1           ", "CombAlp     ",
 
30
//  "Texel0_Alpha", "Texel1_Alpha",
 
31
//  "Prim_Alpha  ", "Shade_Alpha ",
 
32
//  "Env_Alpha   ", "LOD_Fraction",
 
33
//  "PrimLODFrac ", "K5          ",
 
34
//  "?           ", "?           ",
 
35
//  "?           ", "?           ",
 
36
//  "?           ", "?           ",
 
37
//  "?           ", "?           ",
 
38
//  "?           ", "?           ",
 
39
//  "?           ", "?           ",
 
40
//  "?           ", "?           ",
 
41
//  "?           ", "0           "
 
42
//};
 
43
//const char *sc_colcombtypes16[16] =
 
44
//{
 
45
//  "Combined    ", "Texel0      ",
 
46
//  "Texel1      ", "Prim        ", 
 
47
//  "Shade       ", "Environment ",
 
48
//  "1           ", "CombAlp     ",
 
49
//  "Texel0_Alpha", "Texel1_Alpha",
 
50
//  "Prim_Alp    ", "Shade_Alpha ",
 
51
//  "Env_Alpha   ", "LOD_Fraction",
 
52
//  "PrimLOD_Frac", "0           "
 
53
//};
 
54
//const char *sc_colcombtypes8[8] =
 
55
//{
 
56
//  "Combined    ", "Texel0      ",
 
57
//  "Texel1      ", "Primitive   ", 
 
58
//  "Shade       ", "Environment ",
 
59
//  "1           ", "0           ",
 
60
//};
 
61
 
 
62
#ifdef _DEBUG
 
63
const char *constStrs[] = {
 
64
    "MUX_0",
 
65
    "MUX_1",
 
66
    "MUX_COMBINED",
 
67
    "MUX_TEXEL0",
 
68
    "MUX_TEXEL1",
 
69
    "MUX_PRIM",
 
70
    "MUX_SHADE",
 
71
    "MUX_ENV",
 
72
    "MUX_COMBALPHA",
 
73
    "MUX_T0_ALPHA",
 
74
    "MUX_T1_ALPHA",
 
75
    "MUX_PRIM_ALPHA",
 
76
    "MUX_SHADE_ALPHA",
 
77
    "MUX_ENV_ALPHA",
 
78
    "MUX_LODFRAC",
 
79
    "MUX_PRIMLODFRAC",
 
80
    "MUX_K5",
 
81
    "MUX_UNK",
 
82
};
 
83
 
 
84
const char *cycleTypeStrs[] = {
 
85
    "1 Cycle",
 
86
    "2 Cycle",
 
87
    "Copy Mode",
 
88
    "Fill Mode"
 
89
};
 
90
 
 
91
const char* constStr(uint32 op)
 
92
{
 
93
if(op<=MUX_UNK)
 
94
    return constStrs[op];
 
95
else
 
96
   return "Invalid-Const";
 
97
}
 
98
#endif
 
99
 
 
100
void swap(uint8 &a, uint8 &b)
 
101
{
 
102
    uint8 c=a;
 
103
    a=b;
 
104
    b=c;
 
105
}
 
106
 
 
107
 
 
108
//========================================================================
 
109
 
 
110
//========================================================================
 
111
 
 
112
inline IColor GetIColor(uint8 flag, uint32 curCol)
 
113
{
 
114
    IColor newc;
 
115
    switch(flag&MUX_MASK)
 
116
    {
 
117
    case MUX_0:
 
118
        newc = 0;
 
119
        break;
 
120
    case MUX_1:
 
121
        newc = 0xFFFFFFFF;
 
122
        break;
 
123
    case MUX_PRIM:
 
124
        newc = gRDP.primitiveColor;
 
125
        break;
 
126
    case MUX_ENV:
 
127
        newc = gRDP.envColor;
 
128
        break;
 
129
    case MUX_COMBINED:
 
130
    case MUX_SHADE:
 
131
        newc = curCol;
 
132
        break;
 
133
    case MUX_K5:
 
134
        newc = 0xFFFFFFFF;
 
135
        break;
 
136
    case MUX_UNK:
 
137
        newc = curCol;
 
138
        if( options.enableHackForGames == HACK_FOR_CONKER )
 
139
            newc = 0xFFFFFFFF;
 
140
        break;
 
141
    default:
 
142
        newc = curCol;
 
143
        break;
 
144
    }
 
145
 
 
146
    if( flag&MUX_COMPLEMENT )
 
147
    {
 
148
        newc.Complement();
 
149
    }
 
150
 
 
151
    if( flag&MUX_ALPHAREPLICATE )
 
152
    {
 
153
        newc.AlphaReplicate();
 
154
    }
 
155
 
 
156
    return newc;
 
157
}
 
158
 
 
159
COLOR CalculateConstFactor(uint32 colorOp, uint32 alphaOp, uint32 curCol)
 
160
{
 
161
    N64CombinerType m;
 
162
    IColor color(curCol);
 
163
    IColor alpha(curCol);
 
164
 
 
165
    // For color channel
 
166
    *(uint32*)&m = colorOp;
 
167
    if( m.c != MUX_0 && m.a!=m.b)
 
168
    {
 
169
        if( m.a != MUX_0 )  color = GetIColor(m.a, curCol);
 
170
        if( m.b != MUX_0 )  color -= GetIColor(m.b, curCol);
 
171
        if( m.c != MUX_1 )  color *= GetIColor(m.c, curCol);
 
172
    }
 
173
    if( m.d != MUX_0 )  color += GetIColor(m.d, curCol);
 
174
 
 
175
    // For alpha channel
 
176
    *(uint32*)&m = alphaOp;
 
177
    if( m.c != MUX_0 && m.a!=m.b)
 
178
    {
 
179
        if( m.a != MUX_0 )  alpha = GetIColor(m.a, curCol);
 
180
        if( m.b != MUX_0 )  alpha -= GetIColor(m.b, curCol);
 
181
        if( m.c != MUX_1 )  alpha *= GetIColor(m.c, curCol);
 
182
    }
 
183
    if( m.d != MUX_0 )  alpha += GetIColor(m.d, curCol);
 
184
 
 
185
    return (COLOR)(((uint32)color&0x00FFFFFF)|((uint32)alpha&0xFF000000));
 
186
}
 
187
 
 
188
 
 
189
COLOR CColorCombiner::GetConstFactor(uint32 colorFlag, uint32   alphaFlag, uint32 defaultColor)
 
190
{
 
191
    // Allows a combine mode to select what TFACTOR should be
 
192
    uint32 color = defaultColor;
 
193
    uint32 alpha = defaultColor;
 
194
 
 
195
    switch (colorFlag&MUX_MASK)
 
196
    {
 
197
    case MUX_0:
 
198
        break;
 
199
    case MUX_FORCE_0:
 
200
        color = 0;
 
201
        break;
 
202
    case MUX_1:
 
203
        color = 0xFFFFFFFF;
 
204
        break;
 
205
    case MUX_PRIM:
 
206
        color = gRDP.primitiveColor;
 
207
        break;
 
208
    case MUX_ENV:
 
209
        color = gRDP.envColor;
 
210
        break;
 
211
    case MUX_LODFRAC:
 
212
        color = COLOR_RGBA(gRDP.LODFrac, gRDP.LODFrac, gRDP.LODFrac, gRDP.LODFrac);
 
213
        break;
 
214
    case MUX_PRIMLODFRAC:
 
215
        color = COLOR_RGBA(gRDP.primLODFrac, gRDP.primLODFrac, gRDP.primLODFrac, gRDP.primLODFrac);
 
216
        break;
 
217
    case MUX_PRIM_ALPHA:
 
218
        {
 
219
            IColor col(gRDP.primitiveColor);
 
220
            col.AlphaReplicate();
 
221
            color = (COLOR)col;
 
222
        }
 
223
        break;
 
224
    case MUX_ENV_ALPHA:
 
225
        {
 
226
            IColor col(gRDP.envColor);
 
227
            col.AlphaReplicate();
 
228
            color = (COLOR)col;
 
229
        }
 
230
        break;
 
231
    case MUX_K5:
 
232
        color = 0xFFFFFFFF;
 
233
        break;
 
234
    case MUX_UNK:
 
235
        color = defaultColor;
 
236
        if( options.enableHackForGames == HACK_FOR_CONKER ) color = 0xFFFFFFFF;
 
237
        break;
 
238
    default:
 
239
        color = defaultColor;
 
240
        break;
 
241
    }
 
242
 
 
243
    if( colorFlag & MUX_COMPLEMENT )
 
244
    {
 
245
        color = 0xFFFFFFFF - color;
 
246
    }
 
247
    if( colorFlag & MUX_ALPHAREPLICATE )
 
248
    {
 
249
        color = color>>24;
 
250
        color = color | (color<<8) | (color <<16) | (color<<24);
 
251
    }
 
252
 
 
253
    color &= 0x00FFFFFF;    // For color channel only, not the alpha channel
 
254
 
 
255
 
 
256
    switch (alphaFlag&MUX_MASK)
 
257
    {
 
258
    case MUX_0:
 
259
        break;
 
260
    case MUX_FORCE_0:
 
261
        alpha = 0;
 
262
        break;
 
263
    case MUX_1:
 
264
        alpha = 0xFFFFFFFF;
 
265
        break;
 
266
    case MUX_PRIM:
 
267
        alpha = gRDP.primitiveColor;
 
268
        break;
 
269
    case MUX_ENV:
 
270
        alpha = gRDP.envColor;
 
271
        break;
 
272
    case MUX_LODFRAC:
 
273
        alpha = COLOR_RGBA(gRDP.LODFrac, gRDP.LODFrac, gRDP.LODFrac, gRDP.LODFrac);
 
274
        break;
 
275
    case MUX_PRIMLODFRAC:
 
276
        alpha = COLOR_RGBA(gRDP.primLODFrac, gRDP.primLODFrac, gRDP.primLODFrac, gRDP.primLODFrac);
 
277
        break;
 
278
    case MUX_PRIM_ALPHA:
 
279
        {
 
280
            IColor col(gRDP.primitiveColor);
 
281
            col.AlphaReplicate();
 
282
            alpha = (COLOR)col;
 
283
        }
 
284
        break;
 
285
    case MUX_ENV_ALPHA:
 
286
        {
 
287
            IColor col(gRDP.envColor);
 
288
            col.AlphaReplicate();
 
289
            alpha = (COLOR)col;
 
290
        }
 
291
        break;
 
292
    default:
 
293
        alpha = defaultColor;
 
294
        break;
 
295
    }
 
296
 
 
297
    if( alphaFlag & MUX_COMPLEMENT )
 
298
    {
 
299
        alpha = 0xFFFFFFFF - alpha;
 
300
    }
 
301
 
 
302
    alpha &= 0xFF000000;
 
303
 
 
304
    return (color|alpha);
 
305
}
 
306
 
 
307
//*****************************************************************************
 
308
//
 
309
//*****************************************************************************
 
310
//*****************************************************************************
 
311
//
 
312
//*****************************************************************************
 
313
 
 
314
//*****************************************************************************
 
315
//
 
316
//*****************************************************************************
 
317
bool    gUsingPrimColour = false;
 
318
bool    gUsingEnvColour = false;
 
319
 
 
320
int CountTexel1Cycle(N64CombinerType &m)
 
321
{
 
322
    int hasTexel[2];
 
323
    uint8 *p = (uint8*)&m;
 
324
 
 
325
    for( int i=0; i<2; i++)
 
326
    {
 
327
        hasTexel[i]=0;
 
328
        for( int j=0; j<4; j++)
 
329
        {
 
330
            if( (p[j]&MUX_MASK) == MUX_TEXEL0+i )
 
331
            {
 
332
                hasTexel[i]=1;
 
333
                break;
 
334
            }
 
335
        }
 
336
    }
 
337
 
 
338
    return hasTexel[0]+hasTexel[1];
 
339
}
 
340
 
 
341
uint32 GetTexelNumber(N64CombinerType &m)
 
342
{
 
343
    if( (m.a&MUX_MASK) == MUX_TEXEL1 || (m.b&MUX_MASK) == MUX_TEXEL1 || (m.c&MUX_MASK) == MUX_TEXEL1  || (m.d&MUX_MASK) == MUX_TEXEL1 )
 
344
        return TEX_1;
 
345
    else
 
346
        return TEX_0;
 
347
}
 
348
 
 
349
bool IsTxtrUsed(N64CombinerType &m)
 
350
{
 
351
    if( (m.a&MUX_MASK) == MUX_TEXEL1 || (m.b&MUX_MASK) == MUX_TEXEL1 || (m.c&MUX_MASK) == MUX_TEXEL1  || (m.d&MUX_MASK) == MUX_TEXEL1 )
 
352
        return true;
 
353
    if( (m.a&MUX_MASK) == MUX_TEXEL0 || (m.b&MUX_MASK) == MUX_TEXEL0 || (m.c&MUX_MASK) == MUX_TEXEL0  || (m.d&MUX_MASK) == MUX_TEXEL0 )
 
354
        return true;
 
355
    else
 
356
        return false;
 
357
}
 
358
 
 
359
//========================================================================
 
360
 
 
361
void CColorCombiner::InitCombinerMode(void)
 
362
{
 
363
#ifdef _DEBUG
 
364
    LOG_UCODE(cycleTypeStrs[gRDP.otherMode.cycle_type]);
 
365
 
 
366
    if( debuggerDropDecodedMux )
 
367
    {
 
368
        UpdateCombiner(m_pDecodedMux->m_dwMux0, m_pDecodedMux->m_dwMux1);
 
369
    }
 
370
#endif
 
371
 
 
372
    if( currentRomOptions.bNormalCombiner )
 
373
    {
 
374
        DisableCombiner();
 
375
    }
 
376
    else if( gRDP.otherMode.cycle_type  == CYCLE_TYPE_COPY )
 
377
    {
 
378
        InitCombinerCycleCopy();
 
379
        m_bCycleChanged = true;
 
380
    }
 
381
    else if ( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL )
 
382
    //else if ( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL && gRSP.ucode != 5 )   //hack
 
383
    {
 
384
        InitCombinerCycleFill();
 
385
        m_bCycleChanged = true;
 
386
    }
 
387
    else
 
388
    {
 
389
        InitCombinerCycle12();
 
390
        m_bCycleChanged = false;
 
391
    }
 
392
}
 
393
 
 
394
 
 
395
bool bConkerHideShadow=false;
 
396
void CColorCombiner::UpdateCombiner(uint32 dwMux0, uint32 dwMux1)
 
397
{
 
398
#ifdef _DEBUG
 
399
    if( debuggerDropDecodedMux )
 
400
    {
 
401
        debuggerDropDecodedMux = false;
 
402
        m_pDecodedMux->m_dwMux0 = m_pDecodedMux->m_dwMux1 = 0;
 
403
        m_DecodedMuxList.clear();
 
404
    }
 
405
#endif
 
406
 
 
407
    DecodedMux &m_decodedMux = *m_pDecodedMux;
 
408
    if( m_decodedMux.m_dwMux0 != dwMux0 || m_decodedMux.m_dwMux1 != dwMux1 )
 
409
    {
 
410
        if( options.enableHackForGames == HACK_FOR_DR_MARIO )
 
411
        {
 
412
            // Hack for Dr. Mario
 
413
            if( dwMux1 == 0xfffcf239 && 
 
414
                ((m_decodedMux.m_dwMux0 == dwMux0 && dwMux0 == 0x00ffffff && 
 
415
                m_decodedMux.m_dwMux1 != dwMux1 && m_decodedMux.m_dwMux1 == 0xfffcf279 ) || 
 
416
                (m_decodedMux.m_dwMux0 == 0x00ffb3ff && m_decodedMux.m_dwMux1 == 0xff64fe7f && dwMux0 == 0x00ffffff ) ))
 
417
            {
 
418
                //dwMux1 = 0xffcf23A;
 
419
                dwMux1 = 0xfffcf438;
 
420
            }
 
421
        }
 
422
        uint64 mux64 = (((uint64)dwMux1)<<32)+dwMux0;
 
423
        int index=m_DecodedMuxList.find(mux64);
 
424
 
 
425
        if( options.enableHackForGames == HACK_FOR_CONKER )
 
426
        {
 
427
            // Conker's shadow, to disable the shadow
 
428
            //Mux=0x00ffe9ff    Used in CONKER BFD
 
429
            //Color0: (0 - 0) * 0 + SHADE
 
430
            //Color1: (0 - 0) * 0 + SHADE
 
431
            //Alpha0: (1 - TEXEL0) * SHADE + 0
 
432
            //Alpha1: (1 - TEXEL0) * SHADE + 0              
 
433
            if( dwMux1 == 0xffd21f0f && dwMux0 == 0x00ffe9ff )
 
434
            {
 
435
                bConkerHideShadow = true;
 
436
            }
 
437
            else
 
438
            {
 
439
                bConkerHideShadow = false;
 
440
            }
 
441
        }
 
442
 
 
443
        if( index >= 0 )
 
444
        {
 
445
            m_decodedMux = m_DecodedMuxList[index];
 
446
        }
 
447
        else
 
448
        {
 
449
            m_decodedMux.Decode(dwMux0, dwMux1);
 
450
            m_decodedMux.splitType[0] = CM_FMT_TYPE_NOT_CHECKED;
 
451
            m_decodedMux.splitType[1] = CM_FMT_TYPE_NOT_CHECKED;
 
452
            m_decodedMux.splitType[2] = CM_FMT_TYPE_NOT_CHECKED;
 
453
            m_decodedMux.splitType[3] = CM_FMT_TYPE_NOT_CHECKED;
 
454
 
 
455
            m_decodedMux.Hack();
 
456
 
 
457
            if( !m_bSupportMultiTexture )
 
458
            {
 
459
                m_decodedMux.ReplaceVal(MUX_TEXEL1, MUX_TEXEL0);
 
460
                m_decodedMux.ReplaceVal(MUX_LODFRAC,1);
 
461
                m_decodedMux.ReplaceVal(MUX_PRIMLODFRAC,1);
 
462
            }
 
463
 
 
464
            m_decodedMux.Simplify();
 
465
            if( m_supportedStages>1)    
 
466
                m_decodedMux.SplitComplexStages();
 
467
            
 
468
            m_DecodedMuxList.add(m_decodedMux.m_u64Mux, *m_pDecodedMux);
 
469
#ifdef _DEBUG
 
470
            if( logCombiners ) 
 
471
            {
 
472
                TRACE0("Add a new mux");
 
473
                DisplayMuxString();
 
474
            }
 
475
#endif
 
476
        }
 
477
 
 
478
        m_bTex0Enabled = m_decodedMux.m_bTexel0IsUsed;
 
479
        m_bTex1Enabled = m_decodedMux.m_bTexel1IsUsed;
 
480
        m_bTexelsEnable = m_bTex0Enabled||m_bTex1Enabled;
 
481
 
 
482
        gRSP.bProcessDiffuseColor = (m_decodedMux.m_dwShadeColorChannelFlag != MUX_0 || m_decodedMux.m_dwShadeAlphaChannelFlag != MUX_0);
 
483
        gRSP.bProcessSpecularColor = false;
 
484
    }
 
485
}
 
486
 
 
487
 
 
488
#ifdef _DEBUG
 
489
void CColorCombiner::DisplayMuxString(void)
 
490
{
 
491
    if( gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY)
 
492
    {
 
493
        TRACE0("COPY Mode\n");
 
494
    }   
 
495
    else if( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL)
 
496
    {
 
497
        TRACE0("FILL Mode\n");
 
498
    }
 
499
 
 
500
    m_pDecodedMux->DisplayMuxString("Used");
 
501
}
 
502
 
 
503
void CColorCombiner::DisplaySimpleMuxString(void)
 
504
{
 
505
    m_pDecodedMux->DisplaySimpliedMuxString("Used");
 
506
}
 
507
#endif
 
508