1 |
230 |
diegovalve |
// [CORE 0] IP: 38( 1974300ns JNEX 0029 [ 00020000 fffe0000 fffe0000 ][ 00000002 00140000 00000000 ] = [ 00000000 00000000 00000000 ])
|
2 |
|
|
// [CORE 0] IP: 42( 1974320ns NOP 0000 [ 00000000 00020000 00000009 ][ 00000000 00020000 00000009 ] = [ 00000000 00000000 00000000 ])
|
3 |
|
|
// [CORE 0] IP: 43( 1974340ns CALL 00b9 [ 00000000 00000000 00000000 ][ xxxxxxxx xxxxxxxx xxxxxxxx ] = [ 00000000 00000000 00000000 ])
|
4 |
|
|
// [CORE 0] IP: 186( 1974360ns ZERO 0080 [ 00000000 00020000 00000009 ][ 00000000 00020000 00000009 ] = [ 00000000 00000000 00000000 ])
|
5 |
|
|
// [CORE 0] IP: 187( 1974380ns SETY 0049 [ 00020000 00000000 00000000 ][ 00000000 00020000 00000000 ] = [ 00000000 00020000 00000000 ])
|
6 |
|
|
// [CORE 0] IP: 188( 1974400ns SUB 0064 [ fffb0000 00040000 00000000 ][ 00050000 00040000 00000000 ] = [ fff60000 00000000 00000000 ])
|
7 |
|
|
// [CORE 0] IP: 189( 1974420ns SUB 0065 [ fffb0000 fffa0000 00000000 ][ 00050000 00040000 00000000 ] = [ fff60000 fff60000 00000000 ])
|
8 |
|
|
// [CORE 0] IP: 190( 1974440ns SUB 0058 [ 00000000 00040000 00020000 ][ 00050000 00040000 00000000 ] = [ fffb0000 00000000 00020000 ])
|
9 |
|
|
// [CORE 0] IP: 191( 1974480ns CROSS 0059 [ fffee6b0 fffe5a08 ffffb9ac ][ fff60000 fff60000 00000000 ] = [ fffea05c 00015fa4 fffd40b8 ])
|
10 |
|
|
// [CORE 0] IP: 192( 1974520ns CROSS 005a [ fffb0000 00000000 00020000 ][ fff60000 00000000 00000000 ] = [ 00000000 fff60000 00000000 ])
|
11 |
|
|
// [CORE 0] IP: 193( 1974570ns DOT 0069 [ 00000000 fff60000 00000000 ][ fff60000 fff60000 00000000 ] = [ 00320000 00320000 00320000 ])
|
12 |
|
|
// [CORE 0] IP: 194( 1974620ns DOT 0047 [ fffea05c 00015fa4 fffd40b8 ][ fffb0000 00000000 00020000 ] = [ 0000afd2 0000afd2 0000afd2 ])
|
13 |
|
|
// [CORE 0] IP: 195( 1974640ns XCHANGEY 0069 [ 00320000 00320000 00320000 ][ 0000afd2 0000afd2 0000afd2 ] = [ 00320000 0000afd2 00320000 ])
|
14 |
|
|
// [CORE 0] IP: 196( 1974690ns DOT 0047 [ 00000000 fff60000 00000000 ][ fffee6b0 fffe5a08 ffffb9ac ] = [ 00083dd8 00083dd8 00083dd8 ])
|
15 |
|
|
// [CORE 0] IP: 197( 1974710ns XCHANGEZ 0069 [ 00320000 0000afd2 00320000 ][ 00083dd8 00083dd8 00083dd8 ] = [ 00320000 0000afd2 00083dd8 ])
|
16 |
|
|
// [CORE 0] IP: 198( 1974760ns DOT 0066 [ fffea05c 00015fa4 fffd40b8 ][ fff60000 00000000 00000000 ] = [ 0006de34 0006de34 0006de34 ])
|
17 |
|
|
// [CORE 0] IP: 199( 1975420ns DIV 0063 [ 00320000 0000afd2 00083dd8 ][ 0006de34 0006de34 0006de34 ] = [ 000e8f71 00003333 00026666 ])
|
18 |
|
|
// [CORE 0] IP: 200( 1975440ns JGEY 00ca [ 000e8f71 00003333 00026666 ][ 00000000 00000000 00000000 ] = [ 00000000 00000000 00000000 ])
|
19 |
|
|
// [CORE 0] IP: 203( 1975460ns JGEZ 00cd [ 000e8f71 00003333 00026666 ][ 00000000 00000000 00000000 ] = [ 00000000 00000000 00000000 ])
|
20 |
|
|
// [CORE 0] IP: 206( 1975480ns COPY 0047 [ 000e8f71 00003333 00026666 ][ 00000000 00020000 00000009 ] = [ 000e8f71 00003333 00026666 ])
|
21 |
|
|
// [CORE 0] IP: 207( 1975500ns SWIZZLE3D 0047 [ 00000002 00000000 00000000 ][ 000e8f71 00003333 00026666 ] = [ 00026666 00026666 00026666 ])
|
22 |
|
|
// [CORE 0] IP: 208( 1975520ns ADD 0048 [ 00026666 00026666 00026666 ][ 000e8f71 00003333 00026666 ] = [ 0010f5d7 00029999 0004cccc ])
|
23 |
|
|
// [CORE 0] IP: 209( 1975540ns JLEY 00d3 [ 0010f5d7 00029999 0004cccc ][ 00000000 00020000 00000000 ] = [ 00000000 00000000 00000000 ])
|
24 |
|
|
// [CORE 0] IP: 210( 1975560ns NOP 0000 [ 00000000 00020000 00000009 ][ 00000000 00020000 00000009 ] = [ 00000000 00000000 00000000 ])
|
25 |
|
|
// [CORE 0] IP: 211( 1975580ns RET 0076 [ 00000000 00000000 00000000 ][ 00000000 00000000 00000000 ] = [ 00000000 00000000 00000000 ])
|
26 |
|
|
// [CORE 0] IP: 44( 1975620ns NOP 0000 [ 00000000 00020000 00000009 ][ 00000000 00020000 00000009 ] = [ 00000000 00000000 00000000 ])
|
27 |
|
|
// [CORE 0] IP: 45( 1975640ns JEQX 002e [ 00000000 00000000 00000000 ][ 00000000 00000000 00000000 ] = [ 00000000 00000000 00000000 ])
|
28 |
|
|
// [CORE 0] IP: 47( 1975660ns DEC 007b [ 00020000 fffe0000 fffe0000 ][ 00000000 00020000 00000009 ] = [ 00000000 fffc0000 fffc0000 ])
|
29 |
|
|
// [CORE 0] IP: 48( 1975680ns JEQX 0031 [ 00000000 fffc0000 fffc0000 ][ 00000000 00000000 00000000 ] = [ 00000000 00000000 00000000 ])
|
30 |
|
|
// [CORE 0] IP: 50( 1975700ns JEQX 003d [ 00000000 00000000 00000000 ][ 00000000 00000000 00000000 ] = [ 00000000 00000000 00000000 ])
|
31 |
|
|
// [CORE 0] IP: 62( 1975720ns NOP 0000 [ 00000000 00020000 00000009 ][ 00000000 00020000 00000009 ] = [ 00000000 00000000 00000000 ])
|
32 |
|
|
// [CORE 0] IP: 63( 1975740ns CALL 013a [ 00000000 00000000 00000000 ][ xxxxxxxx xxxxxxxx xxxxxxxx ] = [ 00000000 00000000 00000000 ])
|
33 |
|
|
// [CORE 0] IP: 315( 1975780ns OMWRITE 0080 [ 00000000 00000001 00000002 ][ 00000000 00000000 00000000 ] = [ 00000000 00000000 00000000 ])
|
34 |
|
|
// [CORE 0] IP: 316( 1975800ns NOP 0000 [ 00000000 00020000 00000009 ][ 00000000 00020000 00000009 ] = [ 00000000 00000000 00000000 ])
|
35 |
|
|
// [CORE 0] IP: 317( 1975820ns RET 0076 [ 00000001 00000000 00000000 ][ 00000000 00000000 00000000 ] = [ 00000001 00000000 00000000 ])
|
36 |
|
|
// [CORE 0] IP: 64( 1975860ns NOP 0000 [ 00000000 00020000 00000009 ][ 00000000 00020000 00000009 ] = [ 00000000 00000000 00000000 ])
|
37 |
|
|
// [CORE 0] IP: 65( 1975880ns CALL 0051 [ 00000000 00000000 00000000 ][ xxxxxxxx xxxxxxxx xxxxxxxx ] = [ 00000000 00000000 00000000 ])
|
38 |
|
|
// [CORE 0] IP: 82( 1975900ns COPY 007b [ 00000002 00140000 00000000 ][ 00000000 00020000 00000009 ] = [ 00000002 00140000 00000000 ])
|
39 |
|
|
// [CORE 0] IP: 83( 1975920ns ZERO 006e [ 00000000 00020000 00000009 ][ 00000000 00020000 00000009 ] = [ 00000000 00000000 00000000 ])
|
40 |
|
|
// [CORE 0] IP: 84( 1975940ns SETX 006e [ 00060000 00000000 00000000 ][ 00000000 00000000 00000000 ] = [ 00060000 00000000 00000000 ])
|
41 |
|
|
// [CORE 0] IP: 85( 1975960ns ADD 0078 [ 00000000 00000001 00000002 ][ 00000003 00000003 00000003 ] = [ 00000003 00000004 00000005 ])
|
42 |
|
|
// [CORE 0] IP: 86( 1975980ns ADD 006c [ 00000000 00000000 00000000 ][ 00000003 00000003 00000003 ] = [ 00000003 00000003 00000003 ])
|
43 |
|
|
// [CORE 0] IP: 87( 1976000ns COPY 0083 [ 00000003 00000003 00000003 ][ 00000000 00020000 00000009 ] = [ 00000003 00000003 00000003 ])
|
44 |
|
|
// [CORE 0] IP: 88( 1976020ns JGEX 005a [ 00000000 00000000 00000000 ][ 018e0000 00620000 fffe0000 ] = [ 00000000 00000000 00000000 ])
|
45 |
|
|
// [CORE 0] IP: 89( 1976040ns INCX 006f [ 00000000 00000000 00000000 ][ 00000000 00020000 00000009 ] = [ 00020000 00000000 00000000 ])
|
46 |
|
|
// [CORE 0] IP: 90( 1976060ns RET 0076 [ 00000000 00000000 00000000 ][ 00000001 00000000 00000000 ] = [ 00000000 00000000 00000000 ])
|
47 |
|
|
// [CORE 0] IP: 66( 1976100ns NOP 0000 [ 00000000 00020000 00000009 ][ 00000000 00020000 00000009 ] = [ 00000000 00000000 00000000 ])
|
48 |
|
|
// [CORE 0] IP: 67( 1976120ns JNEX 0044 [ 00000000 00000000 00000000 ][ 00000000 00000000 00000000 ] = [ 00000000 00000000 00000000 ])
|
49 |
|
|
// [CORE 0] IP: 67( 1976140ns RETURN 0000 [ 00000001 00000000 00000000 ][ 00000000 00020000 00000009 ] =
|
50 |
|
|
|
51 |
|
|
|
52 |
|
|
// [ 00000001 00000001 00000001 ])
|
53 |
|
|
|
54 |
|
|
|
55 |
|
|
|
56 |
|
|
|
57 |
|
|
//#define r51 r51
|
58 |
|
|
//#define r52 r52
|
59 |
|
|
//#define r53 r53
|
60 |
|
|
//#define r54 r54
|
61 |
|
|
//#define r55 r55
|
62 |
|
|
//#define r56 r56
|
63 |
|
|
//#define r57 r57
|
64 |
|
|
//#define r58 r58
|
65 |
|
|
//#define r59 r59
|
66 |
|
|
//#define r60 r60
|
67 |
|
|
//#define r61 r61
|
68 |
|
|
//#define r62 r62
|
69 |
|
|
////#define CurrentOutputPixel r64
|
70 |
|
|
////#define CurrentTextureColor r65
|
71 |
|
|
//#define r68 r68
|
72 |
|
|
//#define r69 r69
|
73 |
|
|
//#define r60 r60
|
74 |
|
|
////#define TextureColor r61
|
75 |
|
|
//#define r62 r62
|
76 |
|
|
//#define r63 r63
|
77 |
|
|
|
78 |
|
|
//#macro C = DotProduct( A, B )
|
79 |
|
|
// R47 = A * B;
|
80 |
|
|
// R47.x = R47.xxx + R47.yyy;
|
81 |
|
|
// C = R47.xxx + R47.zzz;
|
82 |
|
|
//#endmacro
|
83 |
|
|
|
84 |
|
|
//#macro C = CrossProduct( A, B )
|
85 |
|
|
// R47 = A.yzx * B.zxy;
|
86 |
|
|
// R48 = A.zxy * B.yzx;
|
87 |
|
|
// C = R47 - R48;
|
88 |
|
|
//#endmacro
|
89 |
|
|
|
90 |
|
|
|
91 |
|
|
//Specifiy that the code is using scaled fixed point arithmetic by default
|
92 |
|
|
using fixed_point_arithmetic;
|
93 |
|
|
|
94 |
|
|
r52 = 0x0000147a;
|
95 |
|
|
|
96 |
|
|
r57 = 0;
|
97 |
|
|
r53 = 0xfff80000;
|
98 |
|
|
r53.z = 0;
|
99 |
|
|
|
100 |
|
|
r51 = (0,0x00040000,0x00020000);
|
101 |
|
|
r56 = 2;
|
102 |
|
|
r55 = 2;
|
103 |
|
|
r62 = 10;
|
104 |
|
|
|
105 |
|
|
r69 = (0xfffb0000, 0x00040000, 0x00000000 );
|
106 |
|
|
|
107 |
|
|
r68 = (0x00050000, 0x00040000,0x00000000 );
|
108 |
|
|
|
109 |
|
|
r60 = (0xfffb0000, 0xfffa0000,0x00000000 );
|
110 |
|
|
|
111 |
|
|
|
112 |
|
|
r63.x = 255;
|
113 |
|
|
r63.y = 255;
|
114 |
|
|
r63.z = 255;
|
115 |
|
|
|
116 |
|
|
//----------------------------------------------------------
|
117 |
|
|
function main()
|
118 |
|
|
{
|
119 |
|
|
vector Hit,AllDone;
|
120 |
|
|
vector CurrentOutputPixel = (0,1,2);
|
121 |
|
|
vector CurrentTextureColor = (0xa,0xb,0xc);
|
122 |
|
|
|
123 |
|
|
//Make sure GenerateRay is only called once
|
124 |
|
|
if ( r55 == r56 )
|
125 |
|
|
{
|
126 |
|
|
GenerateRay();
|
127 |
|
|
Hit = 0;
|
128 |
|
|
}
|
129 |
|
|
Hit = CalculateBaricentricIntersection();
|
130 |
|
|
|
131 |
|
|
r55--;
|
132 |
|
|
if ( r55 == 0 ) { exit ; }
|
133 |
|
|
|
134 |
|
|
if (Hit != 0)
|
135 |
|
|
{
|
136 |
|
|
TextureCalculation();
|
137 |
|
|
PrePixelShader();
|
138 |
|
|
}
|
139 |
|
|
|
140 |
|
|
PixelShader( CurrentOutputPixel, CurrentTextureColor );
|
141 |
|
|
GenerateNextPixel();
|
142 |
|
|
|
143 |
|
|
exit ;
|
144 |
|
|
}
|
145 |
|
|
|
146 |
|
|
//----------------------------------------------------------
|
147 |
|
|
function GenerateRay()
|
148 |
|
|
{
|
149 |
|
|
vector UnnormalizedDirection, tmp;
|
150 |
|
|
|
151 |
|
|
UnnormalizedDirection = (r53 + r57 * r52 ) - r51;
|
152 |
|
|
tmp = UnnormalizedDirection * UnnormalizedDirection; //tmp = (x^2,y^2,z^2)
|
153 |
|
|
r54 = UnnormalizedDirection / sqrt( tmp.xxx + tmp.yyy + tmp.zzz );
|
154 |
|
|
|
155 |
|
|
|
156 |
|
|
return ;
|
157 |
|
|
|
158 |
|
|
}
|
159 |
|
|
//---------------------------------------------------------------------
|
160 |
|
|
function CalculateBaricentricIntersection()
|
161 |
|
|
{
|
162 |
|
|
vector E1,E2,T,P,Q,H;
|
163 |
|
|
vector Delta,t;
|
164 |
|
|
|
165 |
|
|
r59 = 0;
|
166 |
|
|
T.y = 1;
|
167 |
|
|
E1 = r69 - r68;
|
168 |
|
|
E2 = r60 - r68;
|
169 |
|
|
T = r51 - r68;
|
170 |
|
|
// P = CrossProduct( r54, E2 );
|
171 |
|
|
R47 = r54.yzx * E2.zxy;
|
172 |
|
|
R48 = r54.zxy * E2.yzx;
|
173 |
|
|
P = R47 - R48;
|
174 |
|
|
// Q = CrossProduct( T, E1 );
|
175 |
|
|
R47 = T.yzx * E1.zxy;
|
176 |
|
|
R48 = T.zxy * E1.yzx;
|
177 |
|
|
Q = R47 - R48;
|
178 |
|
|
// H.x = DotProduct(Q,E2);
|
179 |
|
|
R47 = Q * E2;
|
180 |
|
|
R47.x = R47.xxx + R47.yyy;
|
181 |
|
|
H.x = R47.xxx + R47.zzz;
|
182 |
|
|
// H.y = DotProduct(P,T);
|
183 |
|
|
R47 = P * T;
|
184 |
|
|
R47.x = R47.xxx + R47.yyy;
|
185 |
|
|
H.y = R47.xxx + R47.zzz;
|
186 |
|
|
// H.z = DotProduct( Q, r54 );
|
187 |
|
|
R47 = Q * r54;
|
188 |
|
|
R47.x = R47.xxx + R47.yyy;
|
189 |
|
|
H.z = R47.xxx + R47.zzz;
|
190 |
|
|
// Delta = DotProduct( P, E1 );
|
191 |
|
|
R47 = P * E1;
|
192 |
|
|
R47.x = R47.xxx + R47.yyy;
|
193 |
|
|
Delta = R47.xxx + R47.zzz;
|
194 |
|
|
t = H / Delta;
|
195 |
|
|
|
196 |
|
|
vector ExpectedResult = (0x000e8f71, 0x00003333, 0x00026666);
|
197 |
|
|
if ( t != ExpectedResult)
|
198 |
|
|
{
|
199 |
|
|
R66 = 0xdead;
|
200 |
|
|
exit ;
|
201 |
|
|
} else {
|
202 |
|
|
R66 = 0xaced;
|
203 |
|
|
}
|
204 |
|
|
|
205 |
|
|
if (t.yyy >= 0)
|
206 |
|
|
{
|
207 |
|
|
E2.y = E1.zzz + E1;
|
208 |
|
|
if (E2.yyy > T.yyy)
|
209 |
|
|
{ return 0; }
|
210 |
|
|
|
211 |
|
|
} else {
|
212 |
|
|
return 0;
|
213 |
|
|
}
|
214 |
|
|
|
215 |
|
|
return 1;
|
216 |
|
|
}
|
217 |
|
|
//---------------------------------------------------------------------
|
218 |
|
|
function PixelShader( CurrentOutputPixel, CurrentTextureColor )
|
219 |
|
|
{
|
220 |
|
|
//CurrentOutputPixel = CurrentTextureColor; // What the hell?????
|
221 |
|
|
out [ CurrentOutputPixel ] = CurrentTextureColor.xyz;
|
222 |
|
|
return ;
|
223 |
|
|
}
|
224 |
|
|
//---------------------------------------------------------------------
|
225 |
|
|
function GenerateNextPixel( CurrentOutputPixel, CurrentTextureColor )
|
226 |
|
|
{
|
227 |
|
|
r55 = r56;
|
228 |
|
|
CurrentTextureColor = 0;
|
229 |
|
|
CurrentOutputPixel += 3;
|
230 |
|
|
|
231 |
|
|
|
232 |
|
|
if (r57.xxx >= r62.xxx )
|
233 |
|
|
{
|
234 |
|
|
r57.x++;
|
235 |
|
|
return 0;
|
236 |
|
|
} else {
|
237 |
|
|
r57.x = 0;
|
238 |
|
|
r57.y++;
|
239 |
|
|
if (r57.yyy == r63.yyy)
|
240 |
|
|
{
|
241 |
|
|
return 1;
|
242 |
|
|
} else {
|
243 |
|
|
return 0;
|
244 |
|
|
}
|
245 |
|
|
|
246 |
|
|
}
|
247 |
|
|
}
|
248 |
|
|
//---------------------------------------------------------------------
|
249 |
|
|
//Do this calculation only if this triangle is the one closest to the camera
|
250 |
|
|
function TextureCalculation()
|
251 |
|
|
{
|
252 |
|
|
vector uv_coordinate, fuv, uv1, uv2;
|
253 |
|
|
// vector w1,w2,w3,w4;
|
254 |
|
|
|
255 |
|
|
// //u_coordinate = U0 + last_u * (U1 - U0) + last_v * (U2 - U0);
|
256 |
|
|
// //v_coordinate = r68 + last_u * (r69 - r68) + last_v * (r60 - r68);
|
257 |
|
|
uv_coordinate = Ur68 + last_uv.xxx * (Ur69 - Ur68) + last_uv.yyy * (Ur60 - Ur68);
|
258 |
|
|
|
259 |
|
|
// //fu = (u_coordinate) * gTexture.mWidth
|
260 |
|
|
// //fv = (v_coordinate) * gTexture.mWidth
|
261 |
|
|
fuv.x = (uv_coordinate) * gTextureSize.xxx;
|
262 |
|
|
|
263 |
|
|
// //u1 = ((int)fu) % gTexture.mWidth
|
264 |
|
|
// //v1 = ((int)fv) % gTexture.mHeight
|
265 |
|
|
uv1 = integer( fuv ) % gTextureSize;
|
266 |
|
|
|
267 |
|
|
// //u2 = (u1 + 1 ) % gTexture.mWidth
|
268 |
|
|
// //v2 = (v2 + 1 ) % gTexture.mHeight
|
269 |
|
|
uv2 = (uv1 + 1) % gTextureSize;
|
270 |
|
|
|
271 |
|
|
// //Cool now we should store the values in the appropiate registers
|
272 |
|
|
// //TextureOutputCoord1.x = u1 + v1 * gTexture.mWidth
|
273 |
|
|
// //TextureOutputCoord1.y = u2 + v1 * gTexture.mWidth
|
274 |
|
|
// //TextureOutputCoord1.z = 0
|
275 |
|
|
// //TextureOutputCoord2.x = u1 + v2 * gTexture.mWidth
|
276 |
|
|
// //TextureOutputCoord2.y = u2 + v2 * gTexture.mWidth
|
277 |
|
|
// //TextureOutputCoord2.z = 0
|
278 |
|
|
|
279 |
|
|
// TextureOutputCoord1.x = uv1.xxx + uv1.yyy * gTextureSize.xxx;
|
280 |
|
|
// TextureOutputCoord1.y = uv2.xxx + uv1.yyy * gTextureSize.xxx;
|
281 |
|
|
// TextureOutputCoord1.z = 0;
|
282 |
|
|
|
283 |
|
|
// TextureOutputCoord2.x = uv1.xxx + uv2.yyy * gTextureSize.xxx;
|
284 |
|
|
// TextureOutputCoord2.y = uv2.xxx + uv2.yyy * gTextureSize.xxx;
|
285 |
|
|
// TextureOutputCoord2.z = 0;
|
286 |
|
|
|
287 |
|
|
// //Cool now get the weights
|
288 |
|
|
// //w1.xyz = (1 - fracu) * (1 - fracv)
|
289 |
|
|
// //w2.xyz = fracu * (1 - fracv)
|
290 |
|
|
// //w3.xyz = (1 - fracu) * fracv
|
291 |
|
|
// //w4.xyz = fracu * fracv
|
292 |
|
|
vector ones = (1,1,1);
|
293 |
|
|
vector fracuv;
|
294 |
|
|
|
295 |
|
|
fracuv = fraction( fuv );
|
296 |
|
|
|
297 |
|
|
w1 = ones - fracuv;
|
298 |
|
|
w2 = fracuv * w1.yxz;
|
299 |
|
|
w3 = w2.yyy;
|
300 |
|
|
w2 = w2.xxx;
|
301 |
|
|
w4 = fracuv.xxx * fracuv.yyy;
|
302 |
|
|
|
303 |
|
|
// //All done, let's get out of here
|
304 |
|
|
return ;
|
305 |
|
|
|
306 |
|
|
}
|
307 |
|
|
//---------------------------------------------------------------------
|
308 |
|
|
function PrePixelShader()
|
309 |
|
|
{
|
310 |
|
|
return ;
|
311 |
|
|
}
|
312 |
|
|
//---------------------------------------------------------------------
|
313 |
|
|
|