SCREEN16.C
[目次 | 関数 | マクロ]
1|/***********************************************************************
2| 1. <<< 16bpp グラフィック画面 (Screen16) >>>
3|************************************************************************/
4|
5|#include "mixer_precomp.h" /* Auto precompiled header, Look at mixer-... folder */
6|
7|#include <string.h>
8|
9|#define STDLIBS_INCLUDE
10|#define STDLIBS_INCLUDE_STDIO_H
11|#define STDLIBS_INCLUDE_STRING_H
12|#ifdef USES_MXP_AUTOINC
13| #include "screen16.ah" /* Auto include header, Look at mixer-... folder */
14|#endif
15|
16|
17|
18|
19|/*********************************************************************
20| 2. <<< [Screen16_init] 初期化する >>>
21|【引数】
22| ・void* adr; バッファまたは VRAM の先頭アドレス
23| ・int size; adr のメモリサイズ
24| ・int width, height; 画面のサイズ
25|【補足】
26|・adr には、グラフィックスのフレームバッファに割り当てられている、
27| 仮想アドレスだけでなく、任意のメモリ領域を指定することができます。
28| グローバル変数に char 型の配列を宣言して、その先頭アドレスを
29| 指定することもできます。
30|・adr のバッファに必要なサイズは、width * height * 2 です。
31|*********************************************************************/
32|void Screen16_init( Screen16* m, char* adr, int size,
33| int width, int height )
34|{
35| ASSERT( size >= width * height * 2 );
36|
37| m->adr = (char*)adr;
38| m->width = width;
39| m->height = height;
40|
41| size; /* avoid warning at Release version */
42|}
43|
44|
45|
46|/*********************************************************************
47| 3. <<< [Screen16_print] デバッグ表示する >>>
48|*********************************************************************/
49|#ifndef ERRORS_CUT_DEBUG_TOOL
50|void Screen16_print( Screen16* m, const char* title )
51|{
52| Errors_printf( "%sScreen16: adr=%p, width=%d, height=%d, x+1=[%p], y+1=[%p]", title,
53| m->adr, m->width, m->height,
54| Screen16_pgetAdr( m, 1,0 ), Screen16_pgetAdr( m, 0,1 ) );
55|}
56|#endif
57|
58|
59|
60|/*********************************************************************
61| 4. <<< [Screen16_clear] 画面全体を指定した色でクリアする >>>
62|【補足】
63|・深さ16 の Z バッファとして Screen16 を利用する場合、color には、
64| バッファに設定する Z値を指定してください。
65|*********************************************************************/
66|void Screen16_clear( Screen16* m, int color )
67|{
68| int* p = (int*)m->adr;
69| int* p_over = (int*)(m->adr + m->width * m->height * 2);
70|
71| color = color | (color << 16 );
72|
73| for ( ; p < p_over; p++ ) {
74| *p = color;
75| }
76|}
77|
78|
79|
80|/*********************************************************************
81| 5. <<< [Screen16_pset_f] 点を描画する(関数版)>>>
82|【補足】
83|・DrawScr インターフェイス用です。
84|*********************************************************************/
85|void Screen16_pset_f( Screen16* m, int x, int y, int color )
86|{
87| unsigned short* p = (unsigned short*)Screen16_pgetAdr( m, x, y );
88|
89| *p = (unsigned short)(unsigned int) color;
90|}
91|
92|
93|
94|/************************************************************************
95| 6. <<< [Screen16_putZ] 画面を Z バッファとして Z 値を書き込む >>>
96|【引数】
97| ・int 返り値; 1=書き込んだ, 0=書き込まなかった
98|【補足】
99|・単に Z値を書き込むのではなく、Zバッファに格納されている値より、
100| 引数の Z が小さい場合のみ書き込みます。
101|*************************************************************************/
102|int Screen16_putZ( Screen16* m, int x, int y, int z )
103|{
104| unsigned short* p = (unsigned short*)Screen16_pgetAdr( m, x, y );
105|
106| /*Errors_printf( "Z:[%p] (r=%d, w=%d)", p, (int)*p, z );*/
107|
108| if ( z < (int)*p ) {
109| *p = (unsigned short)(unsigned int) z;
110| return 1;
111| }
112| else
113| return 0;
114|}
115|
116|
117|
118|/***********************************************************************
119| 7. <<< [Screen16_line] 直線を描画する >>>
120|【引数】
121| ・int x1, y1; 直線の端点1のグラフィック座標
122| ・int x2, y2; 直線の端点2のグラフィック座標
123| ・int color; 色(16bpp表現)
124|************************************************************************/
125|void Screen16_line( Screen16* m, int x1, int y1, int x2, int y2, int color )
126|{
127| int x,y;
128| int dx = x2 - x1;
129| int dy = y2 - y1;
130|
131| if ( dx >= 0 ) {
132| if ( dy >= 0 ) {
133| if ( dx >= dy ) { /* RIGHT DOWN */
134| int plus = dy * 2;
135| int cup = plus - dx;
136| int minus = cup - dx;
137|
138| y = y1;
139| for ( x = x1; x <= x2; x++ ) {
140| Screen16_pset_m( m, x, y, color );
141| if ( cup >= 0 ) { y++; cup += minus; }
142| else cup += plus;
143| }
144| }
145| else { /* DOWN RIGHT */
146| int plus = dx * 2;
147| int cup = plus - dy;
148| int minus = cup - dy;
149|
150| x = x1;
151| for ( y = y1; y <= y2; y++ ) {
152| Screen16_pset_m( m, x, y, color );
153| if ( cup >= 0 ) { x++; cup += minus; }
154| else cup += plus;
155| }
156| }
157| }
158| else { /* dy < 0 */
159| if ( dx >= -dy ) { /* RIGHT UP */
160| int plus = -dy * 2;
161| int cup = plus - dx;
162| int minus = cup - dx;
163|
164| y = y1;
165| for ( x = x1; x <= x2; x++ ) {
166| Screen16_pset_m( m, x, y, color );
167| if ( cup >= 0 ) { y--; cup += minus; }
168| else cup += plus;
169| }
170| }
171| else { /* UP RIGHT */
172| int plus = dx * 2;
173| int cup = plus + dy;
174| int minus = cup + dy;
175|
176| x = x1;
177| for ( y = y1; y >= y2; y-- ) {
178| Screen16_pset_m( m, x, y, color );
179| if ( cup >= 0 ) { x++; cup += minus; }
180| else cup += plus;
181| }
182| }
183| }
184| }
185| else { /* dx < 0 */
186| if ( dy >= 0 ) {
187| if ( -dx >= dy ) { /* LEFT DOWN */
188| int plus = dy * 2;
189| int cup = plus + dx;
190| int minus = cup + dx;
191|
192| y = y1;
193| for ( x = x1; x >= x2; x-- ) {
194| Screen16_pset_m( m, x, y, color );
195| if ( cup >= 0 ) { y++; cup += minus; }
196| else cup += plus;
197| }
198| }
199| else { /* DOWN LEFT */
200| int plus = -dx * 2;
201| int cup = plus - dy;
202| int minus = cup - dy;
203|
204| x = x1;
205| for ( y = y1; y <= y2; y++ ) {
206| Screen16_pset_m( m, x, y, color );
207| if ( cup >= 0 ) { x--; cup += minus; }
208| else cup += plus;
209| }
210| }
211| }
212| else { /* dy < 0 */
213| if ( dx < dy ) { /* LEFT UP */
214| int plus = -dy * 2;
215| int cup = plus + dx;
216| int minus = cup + dx;
217|
218| y = y1;
219| for ( x = x1; x >= x2; x-- ) {
220| Screen16_pset_m( m, x, y, color );
221| if ( cup >= 0 ) { y--; cup += minus; }
222| else cup += plus;
223| }
224| }
225| else { /* UP LEFT */
226| int plus = -dx * 2;
227| int cup = plus + dy;
228| int minus = cup + dy;
229|
230| x = x1;
231| for ( y = y1; y >= y2; y-- ) {
232| Screen16_pset_m( m, x, y, color );
233| if ( cup >= 0 ) { x--; cup += minus; }
234| else cup += plus;
235| }
236| }
237| }
238| }
239|}
240|
241|
242|/***********************************************************************
243| 8. <<< [Screen16_pline] 破線を描画する >>>
244|【引数】
245| ・Screen16* m; 8bpp グラフィック画面;
246| ・int x1,y1,x2,y2; 破線の座標
247| ・int color; 色
248| ・void* pattern; 破線のパターン(モノクロ、リトルエンディアン)
249| ・int nPixel; pattern のビット数
250| ・int iStartPixel; 最初に参照するパターンのピクセル番号(0〜 nPixel-1 )
251|【補足】
252|・パターンのピクセル番号は、下位のビットから0、1、2... です。
253|************************************************************************/
254|/* sub routine */
255|/* int getPat( void* pattern, int iPixel ); */
256|#define getPat( pattern, iPixel ) \
257| (*( (int*)(pattern) + (iPixel) / (8*sizeof(int)) ))
258|
259|/* void nextPat( int* pat_adr, int* iPixel_adr, void* pattern, int nPixel ); */
260|#define nextPat( pat_adr, iPixel_adr, nPixel, pattern ) \
261|{ \
262| (*(pat_adr)) >>= 1; (*(iPixel_adr)) ++; \
263| if ( *(iPixel_adr) == (nPixel) ) \
264| { *(iPixel_adr) = 0; *(pat_adr) = *(int*)(pattern); } \
265| else if ( *(iPixel_adr) % (8*sizeof(int)) == 0 ) \
266| *(pat_adr) = getPat( pattern, *(iPixel_adr) ); \
267|}
268|
269|/* main routine */
270|void Screen16_pline( Screen16* m, int x1, int y1, int x2, int y2, int color,
271| void* pattern, int nPixel, int* iStartPixel )
272|{
273| int x,y;
274| int dx = x2 - x1;
275| int dy = y2 - y1;
276| int iPixel; /* ピクセル番号 */
277| int pat; /* パターン 32bit 分をピクセル番号分だけ右シフトしたもの */
278|
279| /* 参照するパターンを初期化する */
280| iPixel = *iStartPixel;
281| pat = getPat( pattern, iPixel );
282| pat >>= (iPixel % (8*sizeof(int)));
283|
284| /* 破線を描画する */
285| if ( dx >= 0 ) {
286| if ( dy >= 0 ) {
287| if ( dx >= dy ) { /* RIGHT DOWN */
288| int plus = dy * 2;
289| int cup = plus - dx;
290| int minus = cup - dx;
291|
292| y = y1;
293| for ( x = x1; x <= x2; x++ ) {
294| if ( pat & 1 )
295| Screen16_pset_m( m, x, y, color );
296| if ( cup >= 0 ) { y++; cup += minus; }
297| else cup += plus;
298| nextPat( &pat, &iPixel, nPixel, pattern );
299| }
300| }
301| else { /* DOWN RIGHT */
302| int plus = dx * 2;
303| int cup = plus - dy;
304| int minus = cup - dy;
305|
306| x = x1;
307| for ( y = y1; y <= y2; y++ ) {
308| if ( pat & 1 )
309| Screen16_pset_m( m, x, y, color );
310| if ( cup >= 0 ) { x++; cup += minus; }
311| else cup += plus;
312| nextPat( &pat, &iPixel, nPixel, pattern );
313| }
314| }
315| }
316| else { /* dy < 0 */
317| if ( dx >= -dy ) { /* RIGHT UP */
318| int plus = -dy * 2;
319| int cup = plus - dx;
320| int minus = cup - dx;
321|
322| y = y1;
323| for ( x = x1; x <= x2; x++ ) {
324| if ( pat & 1 )
325| Screen16_pset_m( m, x, y, color );
326| if ( cup >= 0 ) { y--; cup += minus; }
327| else cup += plus;
328| nextPat( &pat, &iPixel, nPixel, pattern );
329| }
330| }
331| else { /* UP RIGHT */
332| int plus = dx * 2;
333| int cup = plus + dy;
334| int minus = cup + dy;
335|
336| x = x1;
337| for ( y = y1; y >= y2; y-- ) {
338| if ( pat & 1 )
339| Screen16_pset_m( m, x, y, color );
340| if ( cup >= 0 ) { x++; cup += minus; }
341| else cup += plus;
342| nextPat( &pat, &iPixel, nPixel, pattern );
343| }
344| }
345| }
346| }
347| else { /* dx < 0 */
348| if ( dy >= 0 ) {
349| if ( -dx >= dy ) { /* LEFT DOWN */
350| int plus = dy * 2;
351| int cup = plus + dx;
352| int minus = cup + dx;
353|
354| y = y1;
355| for ( x = x1; x >= x2; x-- ) {
356| if ( pat & 1 )
357| Screen16_pset_m( m, x, y, color );
358| if ( cup >= 0 ) { y++; cup += minus; }
359| else cup += plus;
360| nextPat( &pat, &iPixel, nPixel, pattern );
361| }
362| }
363| else { /* DOWN LEFT */
364| int plus = -dx * 2;
365| int cup = plus - dy;
366| int minus = cup - dy;
367|
368| x = x1;
369| for ( y = y1; y <= y2; y++ ) {
370| if ( pat & 1 )
371| Screen16_pset_m( m, x, y, color );
372| if ( cup >= 0 ) { x--; cup += minus; }
373| else cup += plus;
374| nextPat( &pat, &iPixel, nPixel, pattern );
375| }
376| }
377| }
378| else { /* dy < 0 */
379| if ( dx < dy ) { /* LEFT UP */
380| int plus = -dy * 2;
381| int cup = plus + dx;
382| int minus = cup + dx;
383|
384| y = y1;
385| for ( x = x1; x >= x2; x-- ) {
386| if ( pat & 1 )
387| Screen16_pset_m( m, x, y, color );
388| if ( cup >= 0 ) { y--; cup += minus; }
389| else cup += plus;
390| nextPat( &pat, &iPixel, nPixel, pattern );
391| }
392| }
393| else { /* UP LEFT */
394| int plus = -dx * 2;
395| int cup = plus + dy;
396| int minus = cup + dy;
397|
398| x = x1;
399| for ( y = y1; y >= y2; y-- ) {
400| if ( pat & 1 )
401| Screen16_pset_m( m, x, y, color );
402| if ( cup >= 0 ) { x--; cup += minus; }
403| else cup += plus;
404| nextPat( &pat, &iPixel, nPixel, pattern );
405| }
406| }
407| }
408| }
409| *iStartPixel = iPixel;
410|}
411|
412|#undef getPat
413|#undef nextPat
414|
415|/***********************************************************************
416| 9. <<< [Screen16_drawImg] RGB データを画面に表示する・転送する >>>
417|【引数】
418| ・char* img_adr; RGB データの先頭アドレス
419| ・int img_width, img_height; RGB データの大きさ
420| ・int this_x, this_y; 表示位置(RGB データの左上座標)
421|【補足】
422|・任意のアドレスに格納されている RGB データを Screen16 のフレームバッファに
423| 転送します。
424|・RGB データは、フレームバッファと同じ構造にしてください。
425|・img_width が奇数の場合、各行のいちばん左のアドレスが4の倍数になるように
426| RGB データをパディングしてください。(各行のいちばん右の RGB データの次に
427| 1ピクセル分ダミーを入れる。)
428|************************************************************************/
429|void Screen16_drawImg( Screen16* m, char* img_adr,
430| int img_width, int img_height, int this_x, int this_y )
431|{
432| int x,y;
433| int* p;
434| int plus;
435| bool bLast;
436| int* p2 = (int*)img_adr;
437|
438| #if ERRORS_DEBUG_FALSE
439| if ( Errors_count >= Errors_count0 ) {
440| Errors_printf( "Screen16_drawImg()" );
441| Screen16_print( m );
442| Errors_printf( "img: adr=%p, width=%d, height=%d",
443| img_adr, img_width, img_height );
444| Errors_printf( "this_x=%d, this_y=%d", this_x, this_y );
445| }
446| #endif
447|
448| ASSERT( this_x >= 0 );
449| ASSERT( this_y >= 0 );
450| ASSERT( this_x % 4 == 0 );
451| ASSERT( this_y <= m->height );
452| #ifndef NDEBUG
453| if ( this_x > m->width ) {
454| error2_3( Screen16_Err_WidthOver,
455| "イメージの右端が画面から外れます Img.x=%d, Img.w=%d, Scr.w=%d",
456| this_x, img_width, m->width );
457| }
458| #endif
459|
460| p = (int*)Screen16_pgetAdr( m, this_x, this_y );
461| plus = (m->width - img_width) / 2;
462| bLast = ( img_width & 1 );
463|
464| if ( bLast ) {
465| for ( y = 0; y < img_height; y++ ) { /* 水平線の集合 */
466| if ( y >= m->height - this_x ) break;
467| for ( x = 2; x <= img_width; x+=2 ){ /* 32bit の集合 */
468| if ( x <= m->width - this_x ) *p = *p2;
469| p++; p2++;
470| }
471|
472| /* 最後のワード境界に描画する */
473| *p = ( *p2 & 0xFFFF ) | ( *p & 0xFFFF0000 );
474| p++; p2++;
475|
476| p += plus; /* char* 型で加算したほうが高速 */
477| }
478| }
479| else {
480| for ( y = 0; y < img_height; y++ ) { /* 水平線の集合 */
481| if ( y >= m->height - this_y ) break;
482| for ( x = 2; x <= img_width; x+=2 ){ /* 32bit の集合 */
483| if ( x <= m->width - this_x ) *p = *p2;
484| p++; p2++;
485| }
486| p += plus; /* char* 型で加算したほうが高速 */
487| }
488| }
489|}
490|
491|
492|
493|/***********************************************************************
494| 10. <<< [Screen16_drawImgTile] RGB データを画面にタイル表示する >>>
495|【引数】
496| ・char* img_adr; RGB データの先頭アドレス
497| ・int img_width, img_height; RGB データの大きさ
498|************************************************************************/
499|void Screen16_drawImgTile( Screen16* m, char* img_adr,
500| int img_width, int img_height )
501|{
502| int x, y;
503| int plusX = (img_width + 3) & 0xFFFFFFFC;
504| int plusY = img_height;
505|
506| for ( y = 0; y < m->height; y += plusY ) {
507| for ( x = 0; x < m->width; x += plusX ) {
508| Screen16_drawImg( m, img_adr, img_width, img_height, x, y );
509| }
510| }
511|}
512|
513|/***********************************************************************
514| 11. <<< [Screen16_writeBmpFile] ビットマップ・ファイルに出力する >>>
515|【引数】
516| ・char* path; ビットマップ・ファイルのパス
517| ・int x, y; 出力する矩形範囲の左上座標
518| ・int w, h; 出力する矩形範囲の幅と高さ
519|【補足】
520|・Windows 標準のビットマップファイルを作成します。
521|************************************************************************/
522|void Screen16_writeBmpFile( Screen16* m, int x, int y, int w, int h );
523|
524|
525|/***********************************************************************
526| 12. <<< [Screen16_outBmp] 16bpp を任意の bpp に変換する >>>
527|【引数】
528| ・char* buf; フレームバッファの先頭アドレス
529| ・int width,height; buf の幅と高さ(ピクセル数)
530| ・int bpp; buf の BPP(BitParPixel)
531|【補足】
532|・bpp は、8,15,16,24 のうちどれかを指定します。
533|・bpp が 8 の場合、R3G3B2 とします。bpp が 15 の場合、R5G5B5 とします。
534|************************************************************************/
535|#ifdef USES_COLOR
536|void Screen16_outBmp( Screen16* m, char* buf, int width, int height,
537| int bpp )
538|{
539| int x,y,c;
540|
541| ASSERT( bpp == 8 || bpp == 15 || bpp == 16 || bpp == 24 || bpp == 32 );
542|
543| if ( bpp == 8 ) {
544| for ( y = 0; y < height; y++ ) {
545| for ( x = 0; x < width; x++ ) {
546| c = Screen16_pget( m, x, y );
547| ((char*)buf)[x+y*width] = Color_RGB16_getRGB8( c );
548| }
549| }
550| }
551| if ( bpp == 15 ) {
552| for ( y = 0; y < height; y++ ) {
553| for ( x = 0; x < width; x++ ) {
554| c = Screen16_pget( m, x, y );
555| ((short*)buf)[x+y*width] = Color_RGB16_getRGB15( c );
556| }
557| }
558| }
559| if ( bpp == 16 ) {
560| for ( y = 0; y < height; y++ ) {
561| for ( x = 0; x < width; x++ ) {
562| c = Screen16_pget( m, x, y );
563| ((short*)buf)[x+y*width] = c;
564| }
565| }
566| }
567| if ( bpp == 24 ) {
568| for ( y = 0; y < height; y++ ) {
569| for ( x = 0; x < width; x++ ) {
570| c = Screen16_pget( m, x, y );
571| ((char*)buf)[(x+y*width)*3+0] = Color_RGB16_getB8( c );
572| ((char*)buf)[(x+y*width)*3+1] = Color_RGB16_getG8( c );
573| ((char*)buf)[(x+y*width)*3+2] = Color_RGB16_getR8( c );
574| }
575| }
576| }
577| if ( bpp == 32 ) {
578| for ( y = 0; y < height; y++ ) {
579| for ( x = 0; x < width; x++ ) {
580| c = Screen16_pget( m, x, y );
581| ((char*)buf)[(x+y*width)*4+0] = Color_RGB16_getB8( c );
582| ((char*)buf)[(x+y*width)*4+1] = Color_RGB16_getG8( c );
583| ((char*)buf)[(x+y*width)*4+2] = Color_RGB16_getR8( c );
584| }
585| }
586| }
587|}
588|#endif
589|
590|
591|/***********************************************************************
592| 13. <<< [Screen16_isEqualFRB] フレームバッファの内容が同じか判断する >>>
593|************************************************************************/
594|bool Screen16_isEqualFRB( Screen16* a, Screen16* b )
595|{
596| ASSERT( a->width == b->width );
597| ASSERT( a->height == b->height );
598|
599| #ifdef FOR_NSTD
600| return StdX_memcmp( a->adr, b->adr, a->width * a->height * 2 ) == 0;
601| #else
602| return memcmp( a->adr, b->adr, a->width * a->height * 2 ) == 0;
603| #endif
604|}
605|
606|
607|
608|
609|/*************************************************************************
610| 14. <<< [Screen16_paintByMMPaint] ポリゴンを単色で塗りつぶす >>>
611|**************************************************************************/
612|#ifdef USES_MMPAINT
613|#ifdef USES_MASK
614|#ifdef USES_TYPEX
615|void Screen16_paintByMMPaint( Screen16* m, MMPaint* paint, int color )
616|{
617| #define PixelPer32Bit 2
618| int y, ymin, ymax;
619| UINT32 *p, *p2; /* フレームバッファへのポインタ */
620| UINT32* p_x0; /* X座標が 0 の p */
621| UINT32 colorMask = Mask_getColors16bit(color); /* 色のマスク */
622| int add = m->width / 16; /*1つ下の Y 座標のバッファ・アドレスの差分 */
623|
624| ASSERT( m->width % PixelPer32Bit == 0 );
625|
626| /* paint がクリアされていたら、何もしないで関数を抜ける */
627| if ( MMPaint_isNoBound( paint ) ) return;
628|
629| /* 変数の初期化 */
630| ymin = paint->ymin;
631| ymax = paint->ymax;
632|
633| /* 塗りつぶす */
634| p = (UINT32*)Screen16_pgetAdr( m, 0, ymin );
635| p_x0 = p;
636| for ( y = ymin; y <= ymax; y++ ) { /* 水平線の集合 */
637| UINT32 pixelMask;
638| int xmin, xmax;
639|
640| /* 変数の初期化 */
641| xmin = paint->xmin[y-ymin];
642| xmax = paint->xmax[y-ymin];
643|
644| /* 左端と右端を塗る */
645| p = p_x0 + xmin / PixelPer32Bit;
646| p2 = p_x0 + xmax / PixelPer32Bit;
647| if ( p == p2 ) {
648| pixelMask = Mask_leftEnd_for16bpp[xmin & 0x01] &
649| Mask_rightEnd_for16bpp[xmax & 0x01];
650| *p = (pixelMask & colorMask) | (~pixelMask & *p);
651| }
652| else if ( p < p2 ) {
653| pixelMask = Mask_leftEnd_for16bpp[xmin & 0x01];
654| *p = (pixelMask & colorMask) | (~pixelMask & *p);
655| pixelMask = Mask_rightEnd_for16bpp[xmax & 0x01];
656| *p2 = (pixelMask & colorMask) | (~pixelMask & *p2);
657|
658| /* 32bit 単位で間を水平に塗りつぶす */
659| for ( p = p+1; p < p2; p++ )
660| *p = colorMask;
661| }
662|
663| p_x0 += add;
664| }
665| #undef PixelPer32Bit
666|}
667|#endif /* USES_TYPEX */
668|#endif /* USES_MMPAINT */
669|#endif /* USES_MASK */
670|
671|/*************************************************************************
672| 15. <<< [Screen16_psetForCircle] 円描画用の点描画コールバック関数 >>>
673|【補足】
674|・参照:Draw2_circle 関数
675|**************************************************************************/
676|#ifdef USES_DRAW2
677|void Screen16_psetForCircle( void* obj, int cx, int cy, int d1, int d2 )
678|{
679| Screen16_C* m = (Screen16_C*)obj;
680|
681| #if ERRORS_DEBUG_FALSE
682| Errors_printf( "Screen16_psetForCircle: %p, (cx,cy)=(%d,%d), (d1,d2)=(%d,%d)",
683| m, cx, cy, d1, d2 );
684| #endif
685|
686| Screen16_pset( &m->scr, cx+d2, cy+d1, m->color1 ); /* 右下 */
687| Screen16_pset( &m->scr, cx+d2, cy-d1, m->color1 ); /* 右上 */
688| Screen16_pset( &m->scr, cx+d1, cy+d2, m->color1 ); /* 下右 */
689| Screen16_pset( &m->scr, cx-d1, cy+d2, m->color1 ); /* 下左 */
690|
691| Screen16_pset( &m->scr, cx-d2, cy+d1, m->color1 ); /* 左下 */
692| Screen16_pset( &m->scr, cx-d2, cx-d1, m->color1 ); /* 左上 */
693| Screen16_pset( &m->scr, cx+d1, cx-d2, m->color1 ); /* 上右 */
694| Screen16_pset( &m->scr, cx-d1, cx-d2, m->color1 ); /* 上左 */
695|}
696|#endif
697|
698|
699|/*************************************************************************
700| 16. <<< [Screen16_psetForEllipse] 楕円描画用の点描画コールバック関数 >>>
701|【補足】
702|・参照:Draw2_circle 関数
703|**************************************************************************/
704|#ifdef USES_DRAW2
705|void Screen16_psetForEllipse( void* obj, int cx, int cy, int d1, int d2 )
706|{
707| Screen16_C* m = (Screen16_C*)obj;
708|
709| #if ERRORS_DEBUG_FALSE
710| Errors_printf( "Screen16_psetForCircle: %p, (cx,cy)=(%d,%d), (d1,d2)=(%d,%d)",
711| m, cx, cy, d1, d2 );
712| #endif
713|
714| Screen16_pset( &m->scr, cx+d1, cy+d2, m->color1 ); /* 右下 */
715| Screen16_pset( &m->scr, cx-d1, cy+d2, m->color1 ); /* 左下 */
716|
717| Screen16_pset( &m->scr, cx+d1, cx-d2, m->color1 ); /* 右上 */
718| Screen16_pset( &m->scr, cx-d1, cx-d2, m->color1 ); /* 左上 */
719|}
720|#endif
721|
722|/***********************************************************************
723| 17. <<< [Screen16_drawPolyByDDA] DDA 機能を用いてポリゴンを描画する >>>
724|【引数】
725| ・Screen16* screen; 描画対象画面
726| ・Screen16* zbuf; Zバッファ
727| ・MMPaint2* poly; ポリゴンデータ
728|【補足】
729|・必要に応じて、screen や zbuf をクリアしてから呼び出してください。
730|************************************************************************/
731|#ifdef USES_MMPAINT2
732|#ifdef USES_D54SOFT
733|void Screen16_drawPolyByDDA( Screen16* screen, Screen16* zbuf,
734| MMPaint2* poly )
735|{
736| int r;
737| D54Soft_DDA16 dda;
738| MMPaint2_Point* left = MMPaint2_getLeftPoint(poly);
739| MMPaint2_Point* right = MMPaint2_getRightPoint(poly);
740| int dx;
741| int start_r, delta_r; /* DDAの赤色の開始番号と差分番号(固定小数)*/
742| int start_g, delta_g; /* DDAの緑色の開始番号と差分番号(固定小数)*/
743| int start_b, delta_b; /* DDAの青色の開始番号と差分番号(固定小数)*/
744| int start_z, delta_z, delta_z_dec; /* 同、Z 値, dec=小数 */
745|
746| D54Soft_DDA16_init( &dda, screen, zbuf );
747|
748| /* 水平線をいくつも塗って、全体としてポリゴンを塗る */
749| for( r = 0; ; ) { /* 水平線の集合 */
750|
751| /* DDA のパラメータを計算する */
752| dx = right->x - left->x;
753| start_r = left->r; /* delta_r のため後でシフトする */
754| start_g = left->g;
755| start_b = left->b;
756| start_z = left->z;
757| if ( dx != 0 ) {
758| delta_r = (( right->r - start_r ) << D54R_DLR_SFT) / dx;
759| delta_g = (( right->g - start_g ) << D54R_DLG_SFT) / dx;
760| delta_b = (( right->b - start_b ) << D54R_DLB_SFT) / dx;
761| if ( right->z < left->z )
762| delta_z = -(left->z - right->z + dx - 1) / dx;
763| else
764| delta_z = (right->z - left->z) / dx;
765| delta_z_dec = ( ((right->z - left->z) << 16) /dx ) << 16;
766| delta_z_dec += 0x8000; /* 四捨五入 */
767| }
768| start_r <<= D54R_CRS_SFT;
769| start_g <<= D54R_CGS_SFT;
770| start_b <<= D54R_CBS_SFT;
771|
772| /* DDA 機能を起動する */
773| D54Soft_DDA16_runFor3D( &dda, left->x, right->x, left->y,
774| start_r, delta_r, start_g, delta_g, start_b, delta_b,
775| start_z, 0, delta_z, delta_z_dec );
776|
777| if ( r != 0 ) break; /* 最後の水平線を塗ってから抜ける */
778|
779| /* 水平線を1ピクセル下にする */
780| r = MMPaint2_nextLine( poly );
781| }
782|}
783|#endif /* USES_D54SOFT */
784|#endif /* USES_MMPAINT2 */
785|
786|
787|
788|/***********************************************************************
789| 18. <<< [Screen16_drawPolyByDDA_V] DDA 機能を用いてポリゴンを描画する >>>
790|【引数】
791| ・Screen16* screen; 描画対象画面
792| ・Screen16* zbuf; Zバッファ
793| ・MMPaint2_V* poly; ポリゴンデータ
794|【補足】
795|・内部で使用する D54Soft_DDA16_runFor3D_V が無いため
796| 使用できません。
797|・Screen16_drawPolyByDDA との違いは、poly の型です。
798|************************************************************************/
799|#ifdef USES_MMPAINT2
800|#ifdef USES_D54SOFT
801|#if 0
802|void Screen16_drawPolyByDDA_V( Screen16* screen, Screen16* zbuf,
803| MMPaint2_V* poly )
804|{
805| int r;
806| D54Soft_DDA16 dda;
807| MMPaint2_Point* top = MMPaint2_V_getTopPoint(poly);
808| MMPaint2_Point* bottom = MMPaint2_V_getBottomPoint(poly);
809| int dy;
810| int start_r, delta_r; /* DDAの赤色の開始番号と差分番号(固定小数)*/
811| int start_g, delta_g; /* DDAの緑色の開始番号と差分番号(固定小数)*/
812| int start_b, delta_b; /* DDAの青色の開始番号と差分番号(固定小数)*/
813| int start_z, delta_z, delta_z_dec; /* 同、Z 値, dec=小数 */
814|
815| D54Soft_DDA16_init( &dda, screen, zbuf );
816|
817| /* 水平線をいくつも塗って、全体としてポリゴンを塗る */
818| for( r = 0; ; ) { /* 水平線の集合 */
819|
820| /* DDA のパラメータを計算する */
821| dy = bottom->y - top->y;
822| start_r = top->r; /* delta_r のため後でシフトする */
823| start_g = top->g;
824| start_b = top->b;
825| start_z = top->z;
826| if ( dy != 0 ) {
827| delta_r = (( bottom->r - start_r ) << D54R_DLR_SFT) / dy;
828| delta_g = (( bottom->g - start_g ) << D54R_DLG_SFT) / dy;
829| delta_b = (( bottom->b - start_b ) << D54R_DLB_SFT) / dy;
830| if ( bottom->z < top->z )
831| delta_z = -(top->z - bottom->z + dy - 1) / dy;
832| else
833| delta_z = (bottom->z - top->z) / dy;
834| delta_z_dec = ( ((bottom->z - top->z) << 16) /dy ) << 16;
835| delta_z_dec += 0x8000; /* 四捨五入 */
836| }
837| start_r <<= D54R_CRS_SFT;
838| start_g <<= D54R_CGS_SFT;
839| start_b <<= D54R_CBS_SFT;
840|
841| /* DDA 機能を起動する */
842| D54Soft_DDA16_runFor3D_V( &dda, top->x, top->y, bottom->y,
843| start_r, delta_r, start_g, delta_g, start_b, delta_b,
844| start_z, 0, delta_z, delta_z_dec );
845|
846| if ( r != 0 ) break; /* 最後の水平線を塗ってから抜ける */
847|
848| /* 水平線を1ピクセル下にする */
849| r = MMPaint2_V_nextLine( poly );
850| }
851|}
852|#endif
853|#endif /* USES_D54SOFT */
854|#endif /* USES_MMPAINT2 */
855|
856|
857|
858|/***********************************************************************
859| 19. <<< [Screen16_inf_DrawScr] DrawScr インターフェイス >>>
860|************************************************************************/
861|#ifdef USES_DRAWSCR
862|INF_SUB_FUNC( Screen16, DrawScr, Screen16_by_DrawScr )
863|
864|DrawScr Screen16_inf_DrawScr( Screen16* m )
865|{
866| INF_SUB_SC_START( Screen16, DrawScr );
867| INF_SUB_SC_METHOD_NULL( Screen16,getWidth )
868| INF_SUB_SC_METHOD_NULL( Screen16,getHeight )
869| INF_SUB_SC_METHOD_NULL( Screen16,getExAdr )
870| INF_SUB_SC_METHOD_NULL( Screen16,getExVectors )
871| INF_SUB_SC_METHOD_1( Screen16,clear, void, Screen16_clear, Screen16*,int )
872| INF_SUB_SC_METHOD_3( Screen16,pset, void, Screen16_pset_f, Screen16*,int,int,int )
873| INF_SUB_SC_METHOD_NULL( Screen16,exPset )
874| INF_SUB_SC_METHOD_NULL( Screen16,psetXor )
875| #ifdef USES_MASK
876| INF_SUB_SC_METHOD_NULL( Screen16,psets )
877| #endif
878| INF_SUB_SC_METHOD_NULL( Screen16,xorPaint )
879| #ifdef USES_MASK
880| INF_SUB_SC_METHOD_NULL( Screen16,flushTo2 )
881| #ifdef USES_SCREEN
882| INF_SUB_SC_METHOD_NULL( Screen16,flushFromScreen2 )
883| #endif
884| #ifdef USES_DSCREEN
885| INF_SUB_SC_METHOD_NULL( Screen16,flushFromDScreen2 )
886| #endif
887| #endif /* USES_MASK */
888| INF_SUB_SC_END( Screen16, DrawScr );
889|}
890|#endif /* USES_DRAWSCR */
891|
892|