1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     lyt_DrawerGraphics.cpp
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Revision: 27654 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "precompiled.h"
17 #include <nw/lyt/lyt_Drawer.h>
18 #include <nw/lyt/lyt_Layout.h>
19 #include <nw/lyt/lyt_TextBox.h>
20 #include <nw/lyt/lyt_Material.h>
21 #include <nw/lyt/lyt_DrawerCommand.h>
22 #include <nw/lyt/lyt_DrawInfo.h>
23 #include <nw/lyt/lyt_GraphicsResource.h>
24 #include <nw/font/font_DispStringBuffer.h>
25 
26 #ifdef NW_LYT_DRAWER_ENABLE
27 
28 #define TEX_ENV_COLOR_OFFS            3
29 
30 extern unsigned* __cb_current_command_buffer;
31 
32 namespace nw { namespace lyt {
33 
34 void
SetUpTexEnv(const Material * __restrict pMaterial)35 Drawer::SetUpTexEnv( const Material* __restrict pMaterial )
36 {
37 #if ! defined(NW_RELEASE)
38     m_PreviousTexEnvType = m_CurrentTexEnvType;
39 #endif
40 
41     if ( pMaterial->GetTextureOnly() )
42     {
43         switch ( m_CurrentTexEnvType )
44         {
45         case TEX_ENV_TYPE_0_TEX:
46         case TEX_ENV_TYPE_1_TEX:
47             break;
48 
49         default:
50             FlushBuffer();
51             break;
52         }
53 
54         return;
55     }
56 
57 #ifdef NW_LYT_DRAWER_ENABLE_ALPHA_TEST
58     // アルファテストの設定
59     if ( pMaterial->IsAlphaCompareCap() )
60     {
61         FlushBuffer();
62         m_AlphaTestEnable = true;
63 
64         SetUpAlphaTest( pMaterial );
65     }
66     else if ( m_AlphaTestEnable )
67     {
68         // デフォルト(アルファテストなし)に戻す設定
69         FlushBuffer();
70         m_AlphaTestEnable = false;
71 
72         // 0x104
73         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
74             PICA_REG_FRAGOP_ALPHA_TEST,
75             PICA_CMD_DATA_FRAGOP_ALPHA_TEST_DISABLE() );
76     }
77 #endif
78 
79 #ifdef NW_LYT_DRAWER_ENABLE_BLEND_FUNC
80     // ブレンドモードの設定
81     if ( pMaterial->IsBlendModeCap() )
82     {
83         FlushBuffer();
84         m_IsBlendDefault = false;
85 
86         // ブレンドの設定
87         SetUpBlendMode( pMaterial );
88     }
89     else if ( m_IsBlendDefault == false )
90     {
91         // デフォルト(アルファブレンド)に戻す設定
92         FlushBuffer();
93         m_IsBlendDefault = true;
94 
95         const u32 command[] =
96         {
97             NW_FONT_COMMAND_SET_BLEND_DEFAULT
98         };
99 
100         NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
101     }
102 #endif
103 
104 #ifdef NW_LYT_DRAWER_ENABLE_USER_TEX_ENV
105     //----------------------------------------------------------
106     // ユーザー定義のテクスチャコンバイナの設定
107     if ( pMaterial->GetTevStageNum() > 0 )
108     {
109         FlushBuffer();
110 
111         SetUpGLTexEnvUser( pMaterial );
112 
113         m_CurrentTexEnvType = TEX_ENV_TYPE_USER;
114 
115         return;
116     }
117 #endif
118 
119     //----------------------------------------------------------
120     // プリセットのテクスチャコンバイナの設定
121     switch ( pMaterial->GetTexMapNum() )
122     {
123       case 0:
124         {
125             nw::ut::Color8 white = pMaterial->GetColor( INTERPOLATECOLOR_WHITE );
126 
127             static u32 command[] NW_LYT_DRAWER_ALIGN_32 =
128             {
129                 PICA_CMD_DATA_TEX_ENV_SRC(
130                     PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
131                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
132                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
133                     PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
134                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT, PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT ),
135                 PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV5, 5 ),
136                 PICA_CMD_DATA_TEX_ENV_OPERAND(
137                     PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
138                     PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
139                 PICA_CMD_DATA_TEX_ENV_COMBINE(
140                     PICA_DATA_TEX_ENV_COMBINE_MODULATE,
141                     PICA_DATA_TEX_ENV_COMBINE_MODULATE ),
142                 PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_WHITE,
143                 PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
144             };
145 
146             if ( m_CurrentTexEnvType != TEX_ENV_TYPE_0_TEX )
147             {
148                 FlushBuffer();
149 
150                 *reinterpret_cast< nw::ut::Color8* >( &command[ 4 ] ) = white;
151 
152                 NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
153 
154                 m_CurrentTexEnvType = TEX_ENV_TYPE_0_TEX;
155             }
156             else if ( *reinterpret_cast< nw::ut::Color8* >( &command[ 4 ] ) != white )
157             {
158                 FlushBuffer();
159 
160                 *reinterpret_cast< nw::ut::Color8* >( &command[ 4 ] ) = white;
161 
162                 NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
163                     PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV5 + TEX_ENV_COLOR_OFFS),
164                     command[ 4 ] );
165             }
166 
167             return;
168         }
169       case 1 :
170         {
171 
172             nw::ut::Color8 white = pMaterial->GetColor( INTERPOLATECOLOR_WHITE );
173             nw::ut::Color8 black = pMaterial->GetColor( INTERPOLATECOLOR_BLACK );
174 
175             static u32 command[] NW_LYT_DRAWER_ALIGN_32 =
176             {
177                 PICA_CMD_DATA_TEX_ENV_SRC(
178                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
179                     PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
180                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
181                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
182                     PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
183                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT ),
184                 PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV3, 5 ),
185                 PICA_CMD_DATA_TEX_ENV_OPERAND(
186                     PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_ONE_MINUS_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
187                     PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_ONE_MINUS_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
188                 PICA_CMD_DATA_TEX_ENV_COMBINE(
189                     PICA_DATA_TEX_ENV_COMBINE_MODULATE,
190                     PICA_DATA_TEX_ENV_COMBINE_MODULATE ),
191                 PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
192                 PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
193 
194                 PICA_CMD_DATA_TEX_ENV_SRC(
195                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
196                     PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
197                     PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
198                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
199                     PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
200                     PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS ),
201                 PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV4, 5 ),
202                 PICA_CMD_DATA_TEX_ENV_OPERAND(
203                     PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
204                     PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
205                 PICA_CMD_DATA_TEX_ENV_COMBINE(
206                     PICA_DATA_TEX_ENV_COMBINE_MULT_ADD_DMP,
207                     PICA_DATA_TEX_ENV_COMBINE_MULT_ADD_DMP ),
208                 PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_WHITE,
209                 PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
210 
211                 PICA_CMD_DATA_TEX_ENV_SRC(
212                     PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
213                     PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
214                     PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
215                     PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
216                     PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
217                     PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS ),
218                 PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV5, 5 ),
219                 PICA_CMD_DATA_TEX_ENV_OPERAND(
220                     PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
221                     PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
222                 PICA_CMD_DATA_TEX_ENV_COMBINE(
223                     PICA_DATA_TEX_ENV_COMBINE_MODULATE,
224                     PICA_DATA_TEX_ENV_COMBINE_MODULATE ),
225                 PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
226                 PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
227             };
228 
229             if ( m_CurrentTexEnvType != TEX_ENV_TYPE_1_TEX )
230             {
231                 FlushBuffer();
232 
233                 *reinterpret_cast< nw::ut::Color8* >( &command[ 4 ] ) = black;
234                 *reinterpret_cast< nw::ut::Color8* >( &command[ 10 ] ) = white;
235 
236                 NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
237 
238                 m_CurrentTexEnvType = TEX_ENV_TYPE_1_TEX;
239             }
240             else if ( *reinterpret_cast< nw::ut::Color8* >( &command[ 4 ] ) != black ||
241                       *reinterpret_cast< nw::ut::Color8* >( &command[ 10 ] ) != white )
242             {
243                 FlushBuffer();
244 
245                 *reinterpret_cast< nw::ut::Color8* >( &command[ 4 ] ) = black;
246                 *reinterpret_cast< nw::ut::Color8* >( &command[ 10 ] ) = white;
247 
248                 NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
249                     PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV3 + TEX_ENV_COLOR_OFFS ),
250                     command[ 4 ] );
251 
252                 NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
253                     PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV4 + TEX_ENV_COLOR_OFFS ),
254                     command[ 10 ] );
255             }
256 
257             return;
258         }
259       case 2 :
260         {
261             FlushBuffer();
262 
263             SetUpTexEnvType2( pMaterial );
264 
265             m_CurrentTexEnvType = TEX_ENV_TYPE_2_TEX;
266 
267             return;
268         }
269       case 3 :
270         {
271             FlushBuffer();
272 
273             SetUpTexEnvType3( pMaterial );
274 
275             m_CurrentTexEnvType = TEX_ENV_TYPE_3_TEX;
276             return;
277         }
278     }
279 }
280 
SetUpTexEnvType2(const Material * __restrict pMaterial)281 void Drawer::SetUpTexEnvType2( const Material* __restrict pMaterial )
282 {
283     static u32 command[] NW_LYT_DRAWER_ALIGN_32 =
284     {
285         // Texture0 と Texture1 をブレンド
286         PICA_CMD_DATA_TEX_ENV_SRC(
287             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
288             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE1,
289             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
290             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
291             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE1,
292             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT ),
293         PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV3, 5 ),
294         PICA_CMD_DATA_TEX_ENV_OPERAND(
295             PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_ALPHA,
296             PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
297         PICA_CMD_DATA_TEX_ENV_COMBINE(
298             PICA_DATA_TEX_ENV_COMBINE_INTERPOLATE,
299             PICA_DATA_TEX_ENV_COMBINE_INTERPOLATE ),
300         // cmdPosBlend
301         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
302         PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
303 
304         // 白黒カラーをテクスチャでカラー補間
305         PICA_CMD_DATA_TEX_ENV_SRC(
306             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
307             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS_BUFFER_DMP,
308             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
309             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
310             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS_BUFFER_DMP,
311             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS ),
312         PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV4, 5 ),
313         PICA_CMD_DATA_TEX_ENV_OPERAND(
314             PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
315             PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
316         PICA_CMD_DATA_TEX_ENV_COMBINE(
317             PICA_DATA_TEX_ENV_COMBINE_INTERPOLATE,
318             PICA_DATA_TEX_ENV_COMBINE_INTERPOLATE ),
319         // cmdPosWhite
320         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_WHITE,
321         PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
322 
323         // cmdPosBlack
324         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
325         PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV_BUFFER_COLOR ), // 0x0fd
326 
327         // 頂点カラーと掛け算
328         PICA_CMD_DATA_TEX_ENV_SRC(
329             PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
330             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
331             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
332             PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
333             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
334             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS ),
335         PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV5, 5 ),
336         PICA_CMD_DATA_TEX_ENV_OPERAND(
337             PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
338             PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
339         PICA_CMD_DATA_TEX_ENV_COMBINE(
340             PICA_DATA_TEX_ENV_COMBINE_MODULATE,
341             PICA_DATA_TEX_ENV_COMBINE_MODULATE ),
342         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
343         PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
344 
345         NW_LYT_CMD_DATA_TEX_ENV_BUF_INPUT_THROUGH,
346         PICA_CMD_HEADER_SINGLE_BE( PICA_REG_TEX_ENV_BUFFER_INPUT, 0x2 ) // 0x0e0
347     };
348 
349     nw::ut::Color8 blend = pMaterial->GetColor( TEVKONSTSEL_K5 );
350     nw::ut::Color8 white = pMaterial->GetColor( INTERPOLATECOLOR_WHITE );
351     nw::ut::Color8 black = pMaterial->GetColor( INTERPOLATECOLOR_BLACK );
352 
353     const int cmdPosBlend = 4;
354     const int cmdPosWhite = 10;
355     const int cmdPosBlack = 12;
356 
357     if ( m_CurrentTexEnvType != TEX_ENV_TYPE_2_TEX )
358     {
359         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend ] ) = blend;
360         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosWhite ] ) = white;
361         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlack ] ) = black;
362 
363         NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
364     }
365     else if ( *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend ] ) != blend ||
366               *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosWhite ] ) != white ||
367               *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlack ] ) != black )
368     {
369         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend ] ) = blend;
370         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosWhite ] ) = white;
371         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlack ] ) = black;
372 
373         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
374             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV3 + TEX_ENV_COLOR_OFFS ),
375             command[ cmdPosBlend ] );
376 
377         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
378             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV4 + TEX_ENV_COLOR_OFFS ),
379             command[ cmdPosWhite ] );
380 
381         // 0x0fd
382         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
383             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV_BUFFER_COLOR ),
384             command[ cmdPosBlack ] );
385     }
386 }
387 
SetUpTexEnvType3(const Material * __restrict pMaterial)388 void Drawer::SetUpTexEnvType3( const Material* __restrict pMaterial )
389 {
390     static u32 command[] NW_LYT_DRAWER_ALIGN_32 =
391     {
392         // Texture0 にブレンド率を乗算
393         PICA_CMD_DATA_TEX_ENV_SRC(
394             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
395             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
396             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
397             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
398             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
399             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT ),
400         PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV1, 5 ),
401         PICA_CMD_DATA_TEX_ENV_OPERAND(
402             PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_ALPHA, PICA_DATA_OPE_RGB_SRC_COLOR,
403             PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
404         PICA_CMD_DATA_TEX_ENV_COMBINE(
405             PICA_DATA_TEX_ENV_COMBINE_MODULATE,
406             PICA_DATA_TEX_ENV_COMBINE_MODULATE ),
407         // cmdPosBlend0
408         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
409         PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
410 
411         // Texture1 にブレンド率を乗算
412         PICA_CMD_DATA_TEX_ENV_SRC(
413             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE1,
414             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
415             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
416             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE1,
417             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
418             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS ),
419         PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV2, 5 ),
420         PICA_CMD_DATA_TEX_ENV_OPERAND(
421             PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_B_DMP, PICA_DATA_OPE_RGB_SRC_COLOR,
422             PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_B_DMP, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
423         PICA_CMD_DATA_TEX_ENV_COMBINE(
424             PICA_DATA_TEX_ENV_COMBINE_MULT_ADD_DMP,
425             PICA_DATA_TEX_ENV_COMBINE_MULT_ADD_DMP ),
426         // cmdPosBlend1
427         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
428         PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
429 
430         // Texture2 にブレンド率を乗算
431         PICA_CMD_DATA_TEX_ENV_SRC(
432             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE2,
433             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
434             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
435             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE2,
436             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
437             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS ),
438         PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV3, 5 ),
439         PICA_CMD_DATA_TEX_ENV_OPERAND(
440             PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_G_DMP, PICA_DATA_OPE_RGB_SRC_COLOR,
441             PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_G_DMP, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
442         PICA_CMD_DATA_TEX_ENV_COMBINE(
443             PICA_DATA_TEX_ENV_COMBINE_MULT_ADD_DMP,
444             PICA_DATA_TEX_ENV_COMBINE_MULT_ADD_DMP ),
445         // cmdPosBlend2
446         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
447         PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
448 
449         // 白黒カラーをテクスチャでカラー補間
450         PICA_CMD_DATA_TEX_ENV_SRC(
451             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
452             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS_BUFFER_DMP,
453             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
454             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
455             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS_BUFFER_DMP,
456             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS ),
457         PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV4, 5 ),
458         PICA_CMD_DATA_TEX_ENV_OPERAND(
459             PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
460             PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
461         PICA_CMD_DATA_TEX_ENV_COMBINE(
462             PICA_DATA_TEX_ENV_COMBINE_INTERPOLATE,
463             PICA_DATA_TEX_ENV_COMBINE_INTERPOLATE ),
464         // cmdPosWhite
465         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_WHITE,
466         PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
467 
468         // cmdPosBlack
469         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
470         PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV_BUFFER_COLOR ), // 0x0fd
471 
472         // 頂点カラーと掛け算
473         PICA_CMD_DATA_TEX_ENV_SRC(
474             PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
475             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
476             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
477             PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
478             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
479             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS ),
480         PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV5, 5 ),
481         PICA_CMD_DATA_TEX_ENV_OPERAND(
482             PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
483             PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
484         PICA_CMD_DATA_TEX_ENV_COMBINE(
485             PICA_DATA_TEX_ENV_COMBINE_MODULATE,
486             PICA_DATA_TEX_ENV_COMBINE_MODULATE ),
487         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
488         PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
489 
490         NW_LYT_CMD_DATA_TEX_ENV_BUF_INPUT_THROUGH,
491         PICA_CMD_HEADER_SINGLE_BE( PICA_REG_TEX_ENV_BUFFER_INPUT, 0x2 ) // 0x0e0
492     };
493 
494     nw::ut::Color8 blend = pMaterial->GetColor( TEVKONSTSEL_K5 );
495     nw::ut::Color8 white = pMaterial->GetColor( INTERPOLATECOLOR_WHITE );
496     nw::ut::Color8 black = pMaterial->GetColor( INTERPOLATECOLOR_BLACK );
497 
498     const int cmdPosBlend0 = 4;
499     const int cmdPosBlend1 = 10;
500     const int cmdPosBlend2 = 16;
501     const int cmdPosWhite = 22;
502     const int cmdPosBlack = 24;
503 
504     if ( m_CurrentTexEnvType != TEX_ENV_TYPE_3_TEX )
505     {
506         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend0 ] ) = blend;
507         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend1 ] ) = blend;
508         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend2 ] ) = blend;
509         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosWhite ] ) = white;
510         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlack ] ) = black;
511 
512         NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
513     }
514     else if ( *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend0 ] ) != blend ||
515               *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosWhite ] ) != white ||
516               *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlack ] ) != black )
517     {
518         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend0 ] ) = blend;
519         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend1 ] ) = blend;
520         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend2 ] ) = blend;
521         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosWhite ] ) = white;
522         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlack ] ) = black;
523 
524         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
525             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV1 + TEX_ENV_COLOR_OFFS ),
526             command[ cmdPosBlend0 ] );
527 
528         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
529             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV2 + TEX_ENV_COLOR_OFFS ),
530             command[ cmdPosBlend1 ] );
531 
532         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
533             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV3 + TEX_ENV_COLOR_OFFS ),
534             command[ cmdPosBlend2 ] );
535 
536         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
537             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV4 + TEX_ENV_COLOR_OFFS ),
538             command[ cmdPosWhite ] );
539 
540         // 0x0fd
541         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
542             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV_BUFFER_COLOR ),
543             command[ cmdPosBlack ] );
544     }
545 }
546 
SetUpTextures(const Material * __restrict pMaterial,bool addDisableCommand)547 void Drawer::SetUpTextures( const Material* __restrict pMaterial, bool addDisableCommand )
548 {
549     static u32 command[] NW_LYT_DRAWER_ALIGN_32 =
550     {
551         // 0x082
552         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_SIZE ),
553         // 0x085
554         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_ADDR1 ),
555         // 0x08e
556         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_FORMAT ),
557         // 0x083
558         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_WRAP_FILTER ),
559 
560         // 0x092
561         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE1_SIZE ),
562         // 0x095
563         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE1_ADDR ),
564         // 0x096
565         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE1_FORMAT ),
566         // 0x093
567         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE1_WRAP_FILTER ),
568 
569         // 0x09a
570         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE2_SIZE ),
571         // 0x09d
572         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE2_ADDR ),
573         // 0x09e
574         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE2_FORMAT ),
575         // 0x09b
576         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE2_WRAP_FILTER ),
577     };
578 
579     enum
580     {
581         idxWidthHeight = 0,
582         idxTextureAddr = 2,
583         idxFormat      = 4,
584         idxWrapFilter  = 6,
585         settingSize    = 8,
586         commandSize    = sizeof( u32 ) * settingSize
587     };
588 
589     if ( pMaterial == NULL )
590     {
591         command[ idxTextureAddr ] = PICA_CMD_DATA_ZERO();
592 
593         #if defined(NW_FONT_RECTDRAWER_USE_DRAW_BUFFER)
594             NW_ASSERT(m_UniformAddrIndex == 0);
595         #endif
596 
597         if (addDisableCommand)
598         {
599             DisableTextures();
600         }
601         return;
602     }
603 
604     bool isTexCoordModified = true;
605     #if defined(NW_FONT_RECTDRAWER_USE_DRAW_BUFFER)
606         if (m_UniformAddrIndex > 0) // フラッシュされていない
607         {
608             NW_ASSERT(
609                     m_PreviousTexEnvType == m_CurrentTexEnvType
610                 &&  (m_CurrentTexEnvType == TEX_ENV_TYPE_0_TEX || m_CurrentTexEnvType == TEX_ENV_TYPE_1_TEX));
611             isTexCoordModified = false;
612         }
613     #endif
614 
615     const u32 num = ut::Min( (u32)pMaterial->GetTexMapNum(), (u32)TexMapMax );
616 
617     bool isTexturesModified = false;
618 
619     int texbit = 0;
620     for ( int i = 0; i < num; ++i )
621     {
622         texbit |= 1 << i;
623 
624         const TexMap& __restrict texMap = pMaterial->GetTexMap( i );
625         u32* __restrict c = &command[ i * settingSize ];
626 
627         if ( c[ idxTextureAddr ] != texMap.GetPhysicalAddress() / 8
628           || c[ idxWrapFilter  ] != texMap.GetU32WrapFilter()
629         )
630         {
631             c[ idxWidthHeight ] = texMap.GetU32WidthHeight();
632             c[ idxTextureAddr ] = texMap.GetPhysicalAddress() / 8;
633             c[ idxFormat      ] = texMap.GetU32Format();
634             c[ idxWrapFilter  ] = texMap.GetU32WrapFilter();
635             isTexturesModified = true;
636         }
637     }
638 
639     if (isTexCoordModified || isTexturesModified)
640     {
641         // バッファを書き出しておく
642         FlushBuffer();
643     }
644 
645     // 0x080
646     const u32 texFuncData =
647         PICA_CMD_DATA_TEXTURE_FUNC(
648             PICA_DATA_TEXTURE0_SAMPLER_TYPE_TEXTURE_FALSE /* texture0SamplerType: texbit */,
649             0 /* texture1SamplerType: texbit */,
650             0 /* texture2SamplerType: texbit */,
651             0 /* texture3Texcoord */,
652             0 /* texture3SamplerType */,
653             0 /* texture2Texcoord */,
654             1 /* clearTextureCache */) | texbit;
655 
656     if (isTexCoordModified)
657     {
658         // テクスチャ座標有効化
659         // 0x06f
660         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
661             PICA_CMD_HEADER_SINGLE_BE( PICA_REG_VS_OUT_ATTR_CLK, 0x2 ),
662             PICA_CMD_DATA_VS_GS_OUT_ATTR_CLK(
663                 0 /* verZ */,
664                 0 /* col */,
665                 0 /* tex0 : texbit */,
666                 0 /* tex1 : texbit */,
667                 0 /* tex2 : texbit */,
668                 0 /* tex0_w */,
669                 0 /* view_quat */ ) | texbit << 8 );
670 
671         // サンプラータイプ、座標選択
672         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
673             PICA_CMD_HEADER_SINGLE_BE( PICA_REG_TEXTURE_FUNC, 0xB ),
674             texFuncData );
675     }
676 
677     if (isTexCoordModified || isTexturesModified)
678     {
679         // テクスチャキャッシュをクリア
680         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
681             PICA_CMD_HEADER_SINGLE_BE( PICA_REG_TEXTURE_FUNC, 0x4 ),
682             texFuncData );
683     }
684 
685     if (isTexturesModified)
686     {
687         // コマンドリストに積む
688         NW_FONT_RECTDRAWER_ADD_COMMAND( command, commandSize * num );
689     }
690 }
691 
UniformAndDraw()692 void Drawer::UniformAndDraw()
693 {
694     NW_LYT_DRAWER_ASSERT(m_UniformAddrIndex > 0);
695 
696     { // uUniformAddr へのUniform
697     	const u32 size = SetUniformCommand(m_UniformAddrBuffer, m_UniformAddrIndex);
698         NW_FONT_RECTDRAWER_ADD_COMMAND(m_UniformAddrBuffer, size);
699     }
700 
701     if ( m_UniformMtxIndex > 0 )
702     { // uUniformMtx へのUniform
703 
704         Base::AddUniformMtx();
705     }
706 
707     if ( m_UniformDataIndex > 0 )
708     { // uUniformData へのUniform
709         const u32 size = SetUniformCommand(m_UniformDataBuffer, m_UniformDataIndex);
710         NW_FONT_RECTDRAWER_ADD_COMMAND(m_UniformDataBuffer, size);
711         m_UniformDataIndex = 0;
712     }
713 
714     const int vtxNum = DRAW_VTX_NUM * m_UniformAddrIndex;       // 描画頂点数
715 #if defined(NW_FONT_RECTDRAWER_USE_DRAW_ARRAYS)
716     const u32 vtxIdxAddrOffset = GetVertexIndexAddressOffset(vtxNum);
717 #else
718     const u32 vtxIdxAddrOffset = 0;     // dummy
719 #endif
720 
721     // 頂点シェーダーへ、テクスチャ座標の数の設定
722     // 0x2b1
723     NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
724         PICA_CMD_HEADER_SINGLE( PICA_REG_VS_INT0 ),
725         PICA_CMD_DATA_VS_INT( m_TexCoordNum /* x */ , 0 /* y */, 0 /* z */ ));
726 
727     font::internal::SetVertexNumCmd(&__cb_current_command_buffer, vtxIdxAddrOffset, vtxNum);
728 
729     // コマンドリストに積む
730     NW_FONT_RECTDRAWER_ADD_COMMAND( GetDrawCommands(), GetDrawCommandSize() );
731 
732     // インデックスの初期化
733     m_UniformAddrIndex = 0;
734 }
735 
736 
737 void
SetUpTextBox(const TextBox * __restrict pTextBox,const Material * __restrict pMaterial,const DrawInfo & drawInfo)738 Drawer::SetUpTextBox( const TextBox*  __restrict pTextBox,
739                       const Material* __restrict pMaterial,
740                       const DrawInfo& drawInfo )
741 {
742     font::DispStringBuffer* __restrict pStringBuffer = pTextBox->GetDispStringBuffer();
743 
744     // 文字がなければ終了
745     if (pStringBuffer->IsCommandEmpty())
746     {
747         return;
748     }
749 
750     // テキスト描画を設定
751     m_CurrentTexEnvType = TEX_ENV_TYPE_TEXT;
752 
753     // ブレンドはデフォルト
754     m_IsBlendDefault = true;
755 
756     // アルファテストなし
757     m_AlphaTestEnable = false;
758 
759     // 行列情報の設定
760     pTextBox->GetTextGlobalMtx( (nw::math::MTX34*)m_UniformMtx );
761     m_UniformMtxIndex = 3;
762     Base::AddUniformMtx();  // uUniformMtx へのUniform
763 
764     font::WideTextWriter& writer = drawInfo.GetGraphicsResource()->GetTextWriter();
765     writer.SetDispStringBuffer(pStringBuffer);
766 
767     // テキストカラー
768     ut::Color8 topCol = pTextBox->GetTextColor(TEXTCOLOR_TOP);
769     ut::Color8 btmCol = pTextBox->GetTextColor(TEXTCOLOR_BOTTOM);
770     writer.SetGradationMode(
771         topCol != btmCol ?
772             font::CharWriter::GRADMODE_V:
773             font::CharWriter::GRADMODE_NONE);
774     writer.SetTextColor(topCol, btmCol);
775 
776     // 2色補間+アルファ
777     writer.SetColorMapping(
778         pMaterial->GetColor( INTERPOLATECOLOR_BLACK ),
779         pMaterial->GetColor( INTERPOLATECOLOR_WHITE ));
780     writer.SetAlpha(pTextBox->GetGlobalAlpha());
781 
782     // キャッシュからコマンドを追加
783     writer.UseCommandBuffer();
784 
785     writer.SetDispStringBuffer(NULL);
786 
787     // テクスチャの初期化
788     SetUpTextures( NULL );
789 }
790 
791 #ifdef NW_LYT_DRAWER_ENABLE_USER_TEX_ENV
792 void
SetUpGLTexEnvUser(const Material * __restrict pMaterial)793 Drawer::SetUpGLTexEnvUser( const Material* __restrict pMaterial )
794 {
795     // TODO: マテリアルクラスのメンバの時点でコマンド形式で保持するようにする
796     // TODO: ステージ0を使用する必要があるかの判断を事前に行っておく
797 
798     const int tevSrc[] =
799     {
800         PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
801         PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE1,
802         PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE2,
803         PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE3,
804         PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
805         PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
806         PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
807         PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS_BUFFER_DMP,
808     };
809 
810     const int tevMode[] =
811     {
812         PICA_DATA_TEX_ENV_COMBINE_REPLACE,
813         PICA_DATA_TEX_ENV_COMBINE_MODULATE,
814         PICA_DATA_TEX_ENV_COMBINE_ADD,
815         PICA_DATA_TEX_ENV_COMBINE_ADD_SIGNED,
816         PICA_DATA_TEX_ENV_COMBINE_INTERPOLATE,
817         PICA_DATA_TEX_ENV_COMBINE_SUBTRACT,
818         PICA_DATA_TEX_ENV_COMBINE_ADD_MULT_DMP,
819         PICA_DATA_TEX_ENV_COMBINE_MULT_ADD_DMP,
820     };
821 
822     const int tevOpRgb[] =
823     {
824         PICA_DATA_OPE_RGB_SRC_COLOR,
825         PICA_DATA_OPE_RGB_ONE_MINUS_SRC_COLOR,
826         PICA_DATA_OPE_RGB_SRC_ALPHA,
827         PICA_DATA_OPE_RGB_ONE_MINUS_SRC_ALPHA,
828         PICA_DATA_OPE_RGB_SRC_R_DMP,
829         PICA_DATA_OPE_RGB_ONE_MINUS_SRC_R_DMP,
830         PICA_DATA_OPE_RGB_SRC_G_DMP,
831         PICA_DATA_OPE_RGB_ONE_MINUS_SRC_G_DMP,
832         PICA_DATA_OPE_RGB_SRC_B_DMP,
833         PICA_DATA_OPE_RGB_ONE_MINUS_SRC_B_DMP,
834     };
835 
836     const int tevOpAlp[] =
837     {
838         PICA_DATA_OPE_ALPHA_SRC_ALPHA,
839         PICA_DATA_OPE_ALPHA_ONE_MINUS_SRC_ALPHA,
840         PICA_DATA_OPE_ALPHA_SRC_R_DMP,
841         PICA_DATA_OPE_ALPHA_ONE_MINUS_SRC_R_DMP,
842         PICA_DATA_OPE_ALPHA_SRC_G_DMP,
843         PICA_DATA_OPE_ALPHA_ONE_MINUS_SRC_G_DMP,
844         PICA_DATA_OPE_ALPHA_SRC_B_DMP,
845         PICA_DATA_OPE_ALPHA_ONE_MINUS_SRC_B_DMP,
846     };
847 
848     const u32 scale[] =
849     {
850         PICA_DATA_TEX_ENV_SCALE_1,
851         PICA_DATA_TEX_ENV_SCALE_2,
852         PICA_DATA_TEX_ENV_SCALE_4,
853     };
854 
855     const u32 reg[] =
856     {
857         PICA_REG_TEX_ENV0,
858         PICA_REG_TEX_ENV1,
859         PICA_REG_TEX_ENV2,
860         PICA_REG_TEX_ENV3,
861         PICA_REG_TEX_ENV4,
862         PICA_REG_TEX_ENV5,
863     };
864 
865     u32 bufferInput = NW_LYT_CMD_DATA_TEX_ENV_BUF_INPUT_THROUGH;
866 
867     u32 stageNum = nw::ut::Min( (u32)TEX_ENV_STAGE_NUM, (u32)pMaterial->GetTevStageNum() );
868     for ( int i = 0; i < stageNum; ++i )
869     {
870         const TevStage& tevStage = pMaterial->GetTevStage( i );
871 
872         nw::ut::Color8 rgb = pMaterial->GetColor( tevStage.GetKonstSelRgb() );
873         nw::ut::Color8 alpha = pMaterial->GetColor( tevStage.GetKonstSelAlpha() );
874 
875         int stageNo = i + ( TEX_ENV_STAGE_NUM - stageNum );
876 
877         if (i == 0)
878         {
879             // ステージ0を使わなければならないかチェック
880             if ( ( tevStage.GetSrcRgb0() != TEVSRC_CONSTANT &&
881                    tevStage.GetSrcRgb1() != TEVSRC_CONSTANT &&
882                    tevStage.GetSrcRgb2() != TEVSRC_CONSTANT ) ||
883                  ( tevStage.GetSrcAlpha0() != TEVSRC_CONSTANT &&
884                    tevStage.GetSrcAlpha1() != TEVSRC_CONSTANT &&
885                    tevStage.GetSrcAlpha2() != TEVSRC_CONSTANT ) )
886             {
887                 // スルー設定
888                 for ( int j = 1; j <= stageNo; ++j)
889                 {
890                     // ヘッダ
891                     NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
892                         PICA_CMD_HEADER_BURSTSEQ( reg[ j ], 5 ),
893                         PICA_CMD_DATA_TEX_ENV_SRC(
894                             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
895                             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
896                             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
897                             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
898                             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
899                             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT ) );
900 
901                     // 続き
902                     static const u32 command[] =
903                     {
904                         PICA_CMD_DATA_TEX_ENV_OPERAND(
905                             PICA_DATA_OPE_RGB_SRC_COLOR,
906                             PICA_DATA_OPE_RGB_SRC_COLOR,
907                             PICA_DATA_OPE_RGB_SRC_COLOR,
908                             PICA_DATA_OPE_ALPHA_SRC_ALPHA,
909                             PICA_DATA_OPE_ALPHA_SRC_ALPHA,
910                             PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
911                         PICA_CMD_DATA_TEX_ENV_COMBINE(
912                             PICA_DATA_TEX_ENV_COMBINE_REPLACE,
913                             PICA_DATA_TEX_ENV_COMBINE_REPLACE ),
914                         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_WHITE,
915                         PICA_CMD_DATA_TEX_ENV_SCALE(
916                             PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
917                     };
918 
919                     NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
920                 }
921 
922                 // ステージ0を使用
923                 stageNo = 0;
924             }
925         }
926 
927         if ( 1 <= i && i <= 4 )
928         {
929             bufferInput |= PICA_CMD_DATA_TEX_ENV_BUFFER_INPUT(
930                 stageNo,
931                 ( tevStage.GetSavePrevRgb() ) ?
932                     PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS :
933                     PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP,
934                 ( tevStage.GetSavePrevAlpha() ) ?
935                     PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS :
936                     PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP );
937         }
938 
939         const u32 command[] =
940         {
941             PICA_CMD_DATA_TEX_ENV_SRC(
942                 tevSrc[ tevStage.GetSrcRgb0() ],   tevSrc[ tevStage.GetSrcRgb1() ],  tevSrc[ tevStage.GetSrcRgb2() ],
943                 tevSrc[ tevStage.GetSrcAlpha0() ], tevSrc[ tevStage.GetSrcAlpha1()], tevSrc[ tevStage.GetSrcAlpha2() ] ),
944             PICA_CMD_HEADER_BURSTSEQ( reg[ stageNo ], 5 ),
945             PICA_CMD_DATA_TEX_ENV_OPERAND(
946                 tevOpRgb[ tevStage.GetOperandRgb0() ],   tevOpRgb[ tevStage.GetOperandRgb1() ],   tevOpRgb[ tevStage.GetOperandRgb2() ],
947                 tevOpAlp[ tevStage.GetOperandAlpha0() ], tevOpAlp[ tevStage.GetOperandAlpha1() ], tevOpAlp[ tevStage.GetOperandAlpha2() ] ),
948             PICA_CMD_DATA_TEX_ENV_COMBINE( tevMode[ tevStage.GetCombineRgb() ], tevMode[ tevStage.GetCombineAlpha() ] ),
949             NW_LYT_CMD_DATA_COLOR_ALPHA( rgb, alpha ),
950             PICA_CMD_DATA_TEX_ENV_SCALE( scale[ tevStage.GetScaleRgb() ], scale[ tevStage.GetScaleAlpha() ] ),
951         };
952 
953         // コマンドリストに積む
954         NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
955     }
956 
957     // バッファカラーおよびバッファ入力の設定
958     {
959         nw::ut::Color8 black = pMaterial->GetColor( TEVKONSTSEL_BUFFER );
960 
961         // 0x0fd
962         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
963             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV_BUFFER_COLOR ),
964             NW_LYT_CMD_DATA_COLOR(black) );
965 
966         // 0x0e0
967         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
968             PICA_CMD_HEADER_SINGLE_BE( PICA_REG_TEX_ENV_BUFFER_INPUT, 0x2 ),
969             bufferInput );
970     }
971 }
972 #endif
973 
974 #ifdef NW_LYT_DRAWER_ENABLE_ALPHA_TEST
975 void
SetUpAlphaTest(const Material * __restrict pMaterial)976 Drawer::SetUpAlphaTest( const Material* __restrict pMaterial )
977 {
978     const AlphaCompare& __restrict alphaCompare = pMaterial->GetAlphaCompare();
979     register f32 refValue = alphaCompare.GetRef() * 255.f + 0.5f;
980 
981     const u32 alphaTest[] =
982     {
983         PICA_DATA_ALPHA_TEST_NEVER,
984         PICA_DATA_ALPHA_TEST_LESS,
985         PICA_DATA_ALPHA_TEST_LEQUAL,
986         PICA_DATA_ALPHA_TEST_EQUAL,
987         PICA_DATA_ALPHA_TEST_NOTEQUAL,
988         PICA_DATA_ALPHA_TEST_GEQUAL,
989         PICA_DATA_ALPHA_TEST_GREATER,
990         PICA_DATA_ALPHA_TEST_ALWAYS,
991     };
992 
993     // 0x104
994     NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
995         PICA_CMD_HEADER_SINGLE( PICA_REG_FRAGOP_ALPHA_TEST ),
996         PICA_CMD_DATA_FRAGOP_ALPHA_TEST( true, alphaTest[ alphaCompare.GetFunc() ], (u8)refValue ) );
997 }
998 #endif
999 
1000 #ifdef NW_LYT_DRAWER_ENABLE_BLEND_FUNC
1001 void
SetUpBlendMode(const Material * __restrict pMaterial)1002 Drawer::SetUpBlendMode( const Material* __restrict pMaterial )
1003 {
1004     const BlendMode& blendMode = pMaterial->GetBlendMode();
1005 
1006     if ( blendMode.GetBlendOp() == BLENDOP_DISABLE &&
1007          blendMode.GetLogicOp() == LOGICOP_DISABLE )
1008     {
1009         // ブレンドなしのコマンド
1010         u32 command[] =	{
1011             NW_FONT_COMMAND_SET_BLEND_FUNC(
1012                 PICA_DATA_BLEND_EQUATION_ADD,
1013                 PICA_DATA_BLEND_FUNC_ONE,
1014                 PICA_DATA_BLEND_FUNC_ZERO )
1015         };
1016 
1017         NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
1018     }
1019     else if ( blendMode.GetBlendOp() != BLENDOP_DISABLE )
1020     {
1021         // ブレンド設定
1022 
1023         const u32 blendOp[] =
1024         {
1025             0, // DISABLE
1026             PICA_DATA_BLEND_EQUATION_ADD,
1027             PICA_DATA_BLEND_EQUATION_SUBTRACT,
1028             PICA_DATA_BLEND_EQUATION_REVERSE_SUBTRACT,
1029         };
1030 
1031         const u32 srcFactor[] =
1032         {
1033             PICA_DATA_BLEND_FUNC_ZERO,
1034             PICA_DATA_BLEND_FUNC_ONE,
1035             PICA_DATA_BLEND_FUNC_DST_COLOR,
1036             PICA_DATA_BLEND_FUNC_ONE_MINUS_DST_COLOR,
1037             PICA_DATA_BLEND_FUNC_SRC_ALPHA,
1038             PICA_DATA_BLEND_FUNC_ONE_MINUS_SRC_ALPHA,
1039             PICA_DATA_BLEND_FUNC_DST_ALPHA,
1040             PICA_DATA_BLEND_FUNC_ONE_MINUS_DST_ALPHA,
1041         };
1042 
1043         const u32 dstFactor[] =
1044         {
1045             PICA_DATA_BLEND_FUNC_ZERO,
1046             PICA_DATA_BLEND_FUNC_ONE,
1047             PICA_DATA_BLEND_FUNC_SRC_COLOR,
1048             PICA_DATA_BLEND_FUNC_ONE_MINUS_SRC_COLOR,
1049             PICA_DATA_BLEND_FUNC_SRC_ALPHA,
1050             PICA_DATA_BLEND_FUNC_ONE_MINUS_SRC_ALPHA,
1051             PICA_DATA_BLEND_FUNC_DST_ALPHA,
1052             PICA_DATA_BLEND_FUNC_ONE_MINUS_DST_ALPHA,
1053         };
1054 
1055         const u32 command[] =
1056         {
1057             NW_FONT_COMMAND_SET_BLEND_FUNC(
1058                 blendOp[   blendMode.GetBlendOp() ],
1059                 srcFactor[ blendMode.GetSrcFactor() ],
1060                 dstFactor[ blendMode.GetDstFactor() ] ),
1061         };
1062         NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
1063     }
1064     else if ( blendMode.GetLogicOp() != LOGICOP_DISABLE )
1065     {
1066         // 論理演算の設定
1067 
1068         const u32 logicOp[] =
1069         {
1070             0 , // DISABLE
1071             PICA_DATA_LOGIC_NOOP,
1072             PICA_DATA_LOGIC_CLEAR,
1073             PICA_DATA_LOGIC_SET,
1074             PICA_DATA_LOGIC_COPY,
1075             PICA_DATA_LOGIC_COPY_INVERTED,
1076             PICA_DATA_LOGIC_INVERT,
1077             PICA_DATA_LOGIC_AND,
1078             PICA_DATA_LOGIC_NAND,
1079             PICA_DATA_LOGIC_OR,
1080             PICA_DATA_LOGIC_NOR,
1081             PICA_DATA_LOGIC_XOR,
1082             PICA_DATA_LOGIC_EQUIV,
1083             PICA_DATA_LOGIC_AND_REVERSE,
1084             PICA_DATA_LOGIC_AND_INVERTED,
1085             PICA_DATA_LOGIC_OR_REVERSE,
1086             PICA_DATA_LOGIC_OR_INVERTED,
1087         };
1088 
1089         const u32 command[] =
1090         {
1091             NW_LYT_COMMAND_SET_LOGIC_OP( logicOp[ blendMode.GetLogicOp() ] ),
1092         };
1093         NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
1094     }
1095 }
1096 #endif
1097 
1098 }   // namespace lyt
1099 }   // namespace nw
1100 
1101 #endif // NW_LYT_DRAWER_ENABLE
1102