1 // Copyright (C) 2003 Dolphin Project.
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0.
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License 2.0 for more details.
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
15 // Official SVN repository and contact information can be found at
16 // http://code.google.com/p/dolphin-emu/
19 #include "VideoCommon.h"
22 #include "VertexManagerBase.h"
23 #include "VertexShaderManager.h"
24 #include "PixelShaderManager.h"
27 void LoadXFReg(u32 transferSize
, u32 baseAddress
, u32
*pData
)
29 u32 address
= baseAddress
;
30 for (int i
= 0; i
< (int)transferSize
; i
++)
32 address
= baseAddress
+ i
;
35 if (address
< XFMEM_ERROR
)
37 VertexManager::Flush();
38 VertexShaderManager::InvalidateXFRange(address
, address
+ transferSize
);
39 PixelShaderManager::InvalidateXFRange(address
, address
+ transferSize
);
40 //PRIM_LOG("xfmem write: 0x%x-0x%x\n", address, address+transferSize);
42 memcpy_gc((u32
*)&xfmem
[address
], &pData
[i
], transferSize
*4);
45 else if (address
>= XFMEM_SETTEXMTXINFO
&& address
<= XFMEM_SETTEXMTXINFO
+7)
47 xfregs
.texcoords
[address
- XFMEM_SETTEXMTXINFO
].texmtxinfo
.hex
= pData
[i
];
49 else if (address
>= XFMEM_SETPOSMTXINFO
&& address
<= XFMEM_SETPOSMTXINFO
+7)
51 xfregs
.texcoords
[address
- XFMEM_SETPOSMTXINFO
].postmtxinfo
.hex
= pData
[i
];
53 else if (address
>= XFMEM_SETVIEWPORT
&& address
<= XFMEM_SETVIEWPORT
+5)
55 VertexManager::Flush();
56 u32 Index
= address
- XFMEM_SETVIEWPORT
;
57 VertexShaderManager::SetViewport((float*)&pData
[i
],Index
);
58 PixelShaderManager::SetViewport((float*)&pData
[i
],Index
);
65 else if (address
>= XFMEM_SETPROJECTION
&& address
<= XFMEM_SETPROJECTION
+7)
67 VertexManager::Flush();
68 u32 Index
= address
- XFMEM_SETPROJECTION
;
69 VertexShaderManager::SetProjection((float*)&pData
[i
],Index
);
75 else if (address
< 0x2000)
82 case XFMEM_STATE0
: // internal state 0
83 case XFMEM_STATE1
: // internal state 1
85 case XFMEM_SETGPMETRIC
:
88 case XFMEM_CLIPDISABLE
:
89 //if (data & 1) {} // disable clipping detection
90 //if (data & 2) {} // disable trivial rejection
91 //if (data & 4) {} // disable cpoly clipping acceleration
94 case XFMEM_VTXSPECS
: //__GXXfVtxSpecs, wrote 0004
95 xfregs
.hostinfo
= *(INVTXSPEC
*)&data
;
98 case XFMEM_SETNUMCHAN
:
99 if ((u32
)xfregs
.nNumChans
!= (data
& 3))
101 VertexManager::Flush();
102 xfregs
.nNumChans
= data
& 3;
106 case XFMEM_SETCHAN0_AMBCOLOR
: // Channel Ambient Color
107 case XFMEM_SETCHAN1_AMBCOLOR
:
109 u8 chan
= address
- XFMEM_SETCHAN0_AMBCOLOR
;
110 if (xfregs
.colChans
[chan
].ambColor
!= data
)
112 VertexManager::Flush();
113 xfregs
.colChans
[chan
].ambColor
= data
;
114 VertexShaderManager::SetMaterialColor(chan
, data
);
115 PixelShaderManager::SetMaterialColor(chan
, data
);
120 case XFMEM_SETCHAN0_MATCOLOR
: // Channel Material Color
121 case XFMEM_SETCHAN1_MATCOLOR
:
123 u8 chan
= address
- XFMEM_SETCHAN0_MATCOLOR
;
124 if (xfregs
.colChans
[chan
].matColor
!= data
)
126 VertexManager::Flush();
127 xfregs
.colChans
[chan
].matColor
= data
;
128 VertexShaderManager::SetMaterialColor(address
- XFMEM_SETCHAN0_AMBCOLOR
, data
);
129 PixelShaderManager::SetMaterialColor(address
- XFMEM_SETCHAN0_AMBCOLOR
, data
);
134 case XFMEM_SETCHAN0_COLOR
: // Channel Color
135 case XFMEM_SETCHAN1_COLOR
:
137 u8 chan
= address
- XFMEM_SETCHAN0_COLOR
;
138 if (xfregs
.colChans
[chan
].color
.hex
!= (data
& 0x7fff))
140 VertexManager::Flush();
141 xfregs
.colChans
[chan
].color
.hex
= data
;
146 case XFMEM_SETCHAN0_ALPHA
: // Channel Alpha
147 case XFMEM_SETCHAN1_ALPHA
:
149 u8 chan
= address
- XFMEM_SETCHAN0_ALPHA
;
150 if (xfregs
.colChans
[chan
].alpha
.hex
!= (data
& 0x7fff))
152 VertexManager::Flush();
153 xfregs
.colChans
[chan
].alpha
.hex
= data
;
159 if (xfregs
.bEnableDualTexTransform
!= (data
& 1))
161 VertexManager::Flush();
162 xfregs
.bEnableDualTexTransform
= data
& 1;
167 case XFMEM_SETMATRIXINDA
:
168 //_assert_msg_(GX_XF, 0, "XF matrixindex0");
169 VertexShaderManager::SetTexMatrixChangedA(data
); // ?
171 case XFMEM_SETMATRIXINDB
:
172 //_assert_msg_(GX_XF, 0, "XF matrixindex1");
173 VertexShaderManager::SetTexMatrixChangedB(data
); // ?
175 case XFMEM_SETNUMTEXGENS
: // GXSetNumTexGens
176 if ((u32
)xfregs
.numTexGens
!= data
)
178 VertexManager::Flush();
179 xfregs
.numTexGens
= data
;
187 // Maybe these are for Normals?
188 case 0x1048: //xfregs.texcoords[0].nrmmtxinfo.hex = data; break; ??
196 DEBUG_LOG(VIDEO
, "Possible Normal Mtx XF reg?: %x=%x\n", address
, data
);
206 WARN_LOG(VIDEO
, "Unknown XF Reg: %x=%x\n", address
, data
);
213 // TODO - verify that it is correct. Seems to work, though.
214 void LoadIndexedXF(u32 val
, int array
)
216 int index
= val
>> 16;
217 int address
= val
& 0xFFF; // check mask
218 int size
= ((val
>> 12) & 0xF) + 1;
219 //load stuff from array to address in xf mem
221 VertexManager::Flush();
222 VertexShaderManager::InvalidateXFRange(address
, address
+size
);
223 PixelShaderManager::InvalidateXFRange(address
, address
+size
);
224 //PRIM_LOG("xfmem iwrite: 0x%x-0x%x\n", address, address+size);
226 for (int i
= 0; i
< size
; i
++)
227 xfmem
[address
+ i
] = Memory_Read_U32(arraybases
[array
] + arraystrides
[array
] * index
+ i
* 4);