DRAW.C
[目次 | 型・クラス・構造体 | 関数 | マクロ]
1|/**************************************************************************
2|* 1. <<< 描画ツール (Draw) >>>
3|*
4|*・線分や領域塗りつぶしといった基本的な図形を描画するツールです。
5|*・表示画面を Draw_Scr クラスで抽象化しているので、様々な画面に対して
6|* 描画することが出来ます。
7|*
8|*・次のクラスがあります。
9|* ・描画ツール・クラス [Draw]
10|* ・描画ペン・クラス [Draw_Pen]
11|* ・太線タイプ [Draw_BoldType]
12|*
13|*
14|* 2. <<<【解説】基本的な描画の仕方(旧式) >>>
15|*
16|*・アプリケーションは、Draw クラスや XorPaint クラスなど描画関係のコン
17|* ポーネントに対し、線分の描画や塗りつぶしなどのメッセージを送ります。
18|* 描画対象の画面は DrawScr 抽象クラスから継承している Screen, DScreen
19|* または Screen98 クラスのインスタンスであり、それらをアクティブ(描画
20|* 対象)に設定(Draw_setActiveScreen 関数)して描画します。
21|*
22|*
23|*
24|*・地図画面は Screen クラスのインスタンスです。テスト用として PC-98 の
25|* DOS 画面に表示する場合は、 Screen98 クラスのインスタンスを作成します。
26|* ワーク領域として Screen クラスのインスタンスや DScreen クラスのイン
27|* スタンスを作成します。
28|*・アプリケーションが描画する場合は、 Draw クラスか XorPaint クラスの
29|* グローバル・インスタンスに Screen クラスなどの画面インスタンスを
30|* 関連付けてから、そのグローバル・インスタンスにメッセージを送ります。
31|***************************************************************************/
32|
33|#include "mixer_precomp.h"
34|// #pragma hdrstop ("mixer_precomp")
35|
36|#ifdef USES_MXP_AUTOINC
37| #include "draw.ah" /* Auto include header, Look at mixer-... folder */
38|#endif
39|
40|
41|/*************************************************************************
42|* 3. <<< 線分を描く[Draw_line()] >>>
43|**************************************************************************/
44|#define _Draw_line
45|#include "draw.cc"
46|#undef _Draw_line
47|
48|#ifdef USES_TYPEX
49|/*************************************************************************
50|* 4. <<< 線分を描画する [Draw_line2()] >>>
51|*【補足】
52|*・拡張座標値を用いて長い線分を高速に描画します。
53|*・x1,y1,x2,y2 は、画面の中に入っている必要があります。
54|**************************************************************************/
55|void Draw_line2( Draw* m, int x1, int y1, int x2, int y2, int color )
56|{
57| UINT32 exAdr; /* 座標値を表す拡張座標値 */
58| UINT32 exAdr_last; /* 同・終点 */
59| UINT32 plus0, plus1; /* 拡張ベクトル値 */
60| int dx,dy; /* 方向ベクトルの x,y 成分の絶対値 */
61| int dir; /* 方向番号([x1,y1]→[x2,y2])*/
62| int cup, plus, minus; /* Bresenham のアルゴリズムの3変数 */
63| void* obj; /* m->drawScr 画面クラスのアドレス */
64| void (*exPset)(void*,int,int); /* obj クラスの拡張・点描画の関数ポインタ */
65|
66| #ifdef _CHECKER
67| if ( x1 < 0 || x1 >= DrawScr_getWidth( m->drawScr ) ) error();
68| if ( x2 < 0 || x2 >= DrawScr_getWidth( m->drawScr ) ) error();
69| if ( y1 < 0 || y1 >= DrawScr_getHeight( m->drawScr ) ) error();
70| if ( y2 < 0 || y2 >= DrawScr_getHeight( m->drawScr ) ) error();
71| #endif
72|
73| /* x1 <= x2 にする */
74| if ( x1 > x2 ) {
75| int a;
76| a = x1; x1 = x2; x2 = a;
77| a = y1; y1 = y2; y2 = a;
78| }
79|
80| /* 各種変数を初期化する */
81| exAdr = DrawScr_getExAdr( m->drawScr, x1, y1 );
82| exAdr_last = DrawScr_getExAdr( m->drawScr, x2, y2 );
83| dx = x2 - x1;
84| dy = ( y1 < y2 ? y2 - y1 : y1 - y2 );
85| dir = Draw_getDirec( dx, y2 - y1 );
86| DrawScr_getExVectors( m->drawScr, dir, &plus0, &plus1 );
87| if ( dx >= dy ) {
88| plus = 2 * dy; /* plus = 2dy */
89| cup = plus - dx; /* (dy % dx) * 2 */
90| minus = cup - dx; /* minus = -2dx */
91| }
92| else {
93| plus = 2 * dx;
94| cup = plus - dy;
95| minus = cup - dy;
96| }
97| obj = m->drawScr.obj;
98| exPset = m->drawScr.sc->exPset;
99|
100| /* 線を描く(Bresenham のアルゴリズム) */
101| exPset( obj, exAdr, color );
102| while ( exAdr != exAdr_last ) {
103| if ( cup > 0 )
104| { exAdr += plus1; cup += minus; }
105| else
106| { exAdr += plus0; cup += plus; }
107|
108| exPset( obj, exAdr, color );
109| }
110|}
111|#endif /* USES_TYPEX */
112|
113|
114|#ifdef USES_TYPEX
115|#ifdef USES_SCREEN
116|/*************************************************************************
117|* 5. <<< 線分を描画する [Draw_line3()] >>>
118|*【補足】
119|*・マクロ展開しています。レジスタ指定しています。
120|*・Draw の対象は Screen 専用です。
121|*・拡張座標値を用いて長い線分を高速に描画します。
122|*・x1,y1,x2,y2 は、画面の中に入っている必要があります。
123|**************************************************************************/
124|void Draw_line3( Draw* m, int x1, int y1, int x2, int y2, int color )
125|{
126| register UINT32 exAdr; /* 座標値を表す拡張座標値 */
127| register UINT32 exAdr_last; /* 同・終点 */
128| register UINT32 plus0, plus1; /* 拡張ベクトル値 */
129| register int dx,dy; /* 方向ベクトルの x,y 成分の絶対値 */
130| register int dir; /* 方向番号([x1,y1]→[x2,y2])*/
131| register int cup, plus, minus; /* Bresenham のアルゴリズムの3変数 */
132| register Screen* scr = m->drawScr.obj;
133|
134| #ifdef _CHECKER
135| if ( x1 < 0 || x1 >= DrawScr_getWidth( m->drawScr ) ) error();
136| if ( x2 < 0 || x2 >= DrawScr_getWidth( m->drawScr ) ) error();
137| if ( y1 < 0 || y1 >= DrawScr_getHeight( m->drawScr ) ) error();
138| if ( y2 < 0 || y2 >= DrawScr_getHeight( m->drawScr ) ) error();
139| #endif
140|
141| /* x1 <= x2 にする */
142| if ( x1 > x2 ) {
143| int a;
144| a = x1; x1 = x2; x2 = a;
145| a = y1; y1 = y2; y2 = a;
146| }
147|
148| /* 各種変数を初期化する */
149| exAdr = Screen_getExAdr2( scr, x1, y1 );
150| exAdr_last = Screen_getExAdr2( scr, x2, y2 );
151| dx = x2 - x1;
152| dy = ( y1 < y2 ? y2 - y1 : y1 - y2 );
153| Draw_getDirec2( dx, y2 - y1, dir );
154| Screen_getExVectors2( scr, dir, plus0, plus1 );
155| if ( dx >= dy ) {
156| plus = dy << 1; /* plus = 2dy */
157| cup = plus - dx; /* (dy % dx) * 2 */
158| minus = cup - dx; /* minus = -2dx */
159| }
160| else {
161| plus = dx << 1;
162| cup = plus - dy;
163| minus = cup - dy;
164| }
165|
166| /* 線を描く(Bresenham のアルゴリズム) */
167| Screen_exPset2( scr, exAdr, color );
168| while ( exAdr != exAdr_last ) {
169| if ( cup > 0 )
170| { exAdr += plus1; cup += minus; }
171| else
172| { exAdr += plus0; cup += plus; }
173|
174| Screen_exPset2( scr, exAdr, color );
175| }
176|}
177|#endif /* USES_SCREEN */
178|#endif /* USES_TYPEX */
179|
180|
181|/*************************************************************************
182|* 6. <<< 破線を描く[Draw_loseLine()] >>>
183|**************************************************************************/
184|#define _Draw_loseLine
185|#include "draw.cc"
186|#undef _Draw_loseLine
187|
188|
189|/*************************************************************************
190|* 7. <<< コピーラインを描く[Draw_copyLine()] >>>
191|**************************************************************************/
192|#ifdef USES_SCREEN
193|#define _Draw_copyLine
194|#include "draw.cc"
195|#undef _Draw_copyLine
196|#endif
197|
198|
199|/*************************************************************************
200|* 8. <<< 塗りつぶし境界を描く[Draw_lineForXorPaint()] >>>
201|**************************************************************************/
202|void Draw_lineForXorPaint( Draw* m, int x1, int y1, int x2, int y2,
203| int color )
204|{
205| int x,y,n;
206| int dx, dy;
207| register int cup; /* カウンタ */
208| register int plus, minus; /* カウンタの増分、減分 */
209| int flag; /* cup による座標の増減, +1 or -1 */
210| int prevX; /* 直前に描いた点の x 座標 */
211|
212| /* 90度〜270度(左向き)の場合 */
213| if ( x1 > x2 ) {
214| n = x1; x1 = x2; x2 = n;
215| n = y1; y1 = y2; y2 = n;
216| }
217|
218| /* 最初の1点を x, y に color 色で打つ */
219| prevX = x1; /* 最初の1点は描かない */
220|
221| /* dx, dy, flag の設定 */
222| dx = x2 - x1;
223| dy = y2 - y1;
224| if ( dy > 0 )
225| flag = +1;
226| else {
227| flag = -1; dy = -dy;
228| }
229|
230| /* 0度〜45度(水平より右下がり)の場合 */
231| /* 0度〜-45度(水平より右上がり)の場合 */
232| if ( dx >= dy ) {
233| plus = 2 * dy; /* plus = 2dy */
234| cup = plus - dx; /* (dy % dx) * 2 */
235| minus = cup - dx; /* minus = -2dx */
236|
237| y = y1;
238| for ( x = x1 + 1; x <= x2; x++ ) {
239| if ( cup > 0 )
240| { y += flag; cup += minus; }
241| else
242| cup += plus;
243|
244| /* x, y に color 色の点を打つ */
245| Draw_psetXor( m, x, y, color );
246| }
247| }
248|
249| /* 45度〜90度(垂直より右下がり)の場合 */
250| /* -45度〜-90度(垂直より右上がり)の場合 */
251| else {
252| if ( flag < 0 ) {
253| n = x1; x1 = x2; x2 = n;
254| n = y1; y1 = y2; y2 = n;
255|
256| /* 最初の点(右上端点)は必ず描く、ただし、垂直でないとき */
257| if ( x1 != x2 )
258| Draw_psetXor( m, x1, y1, color );
259| prevX = x1;
260| }
261| plus = 2 * dx;
262| cup = plus - dy;
263| minus = cup - dy;
264|
265| x = x1;
266| for ( y = y1 + 1; y <= y2; y ++ ) {
267| if ( cup > 0 )
268| { x += flag; cup += minus; }
269| else
270| cup += plus;
271|
272| /* x, y に color 色の点を打つ */
273| if ( x != prevX && ( flag > 0 || x != x2 ) ) {
274| /* Draw_psetXor( m, x, y, color ); *//*GHSで落ちる*/
275| DrawScr_psetXor( (m)->drawScr, x, y, color );
276| prevX = x;
277| }
278| }
279| }
280|}
281|
282|
283|/**************************************************************************
284|* 9. <<< 太線を描く [Draw_boldLine()] >>>
285|* ・width : 太さ(pixel)
286|* ・type : 筆, 線筆=Draw_BoldType_Line, 丸筆=Draw_BoldType_Circle
287|* Draw_Pen_init() してから実行すること。
288|***************************************************************************/
289|void Draw_boldLine( Draw* m, int x1, int y1, int x2, int y2,
290| int color, int width, int type )
291|{
292| int i;
293|
294| /* 線筆 */
295| if ( type == Draw_BoldType_Line ) {
296| int dx = ( x1 < x2 ? x2 - x1 : x1 - x2 );
297| int dy = ( y1 < y2 ? y2 - y1 : y1 - y2 );
298| if ( dx >= dy ) { /* 水平から 45°以下 */
299| for ( i = -(width-1) / 2; i <= width / 2; i++ )
300| Draw_line( m, x1, y1+i, x2, y2+i, color );
301| }
302| else { /* 垂直から 45°以下 */
303| for ( i = -(width-1) / 2; i <= width / 2; i++ )
304| Draw_line( m, x1+i, y1, x2+i, y2, color );
305| }
306| }
307| /* 丸筆 */
308| else {
309| #ifdef USES_SCREEN
310| int* points = Draw_Pen_maru[width]; /* 筆の形, Draw_Pen_maru[] 変数 */
311|
312| for ( i=0; i < points[0]; i+=2 ) {
313| Draw_line( m, x1 + points[i+1], y1 + points[i+2],
314| x2 + points[i+1], y2 + points[i+2], color );
315| }
316| #else
317| #ifndef NDEBUG
318| error();
319| #endif
320| #endif
321| }
322|}
323|
324|
325|#ifdef USES_SSTACK
326|/**************************************************************************
327|* 10. <<< ベジェ曲線を描く [Draw_bezier(), Draw_bezierForXorPaint()] >>>
328|***************************************************************************/
329|#define Bezier_max 1000 /* ベジェ曲線用スタックのサイズ、点を打つ数 * 2 */
330|
331|typedef struct {
332| int x1,y1, x2,y2, x3,y3, x4,y4;
333|} Draw_BezierCup;
334|
335|void Draw_BezierCup_copy( Draw_BezierCup* a, Draw_BezierCup* b );
336|void Draw_bezierSub( Draw* m, Draw_BezierCup* in,
337| int* x, int* y, Draw_BezierCup* out1, Draw_BezierCup* out2 );
338|
339|#define _Draw_bezier
340|#include "draw.cc"
341|#undef _Draw_bezier
342|
343|#define _Draw_bezierForXorPaint
344|#include "draw.cc"
345|#undef _Draw_bezierForXorPaint
346|
347|
348|/*
349|* ベジェ分割
350|* ベジェ中点と、サブ・ベジェカップ を2つ得る
351|* ・in : ベジェカップ(入力)
352|* ・x, y : ベジェ中点、点を描画する位置(出力)
353|* ・out1, out2 : サブ・ベジェカップ(出力)
354|*/
355|void Draw_bezierSub( Draw* m, Draw_BezierCup* in,
356| int* x, int* y, Draw_BezierCup* out1, Draw_BezierCup* out2 )
357|{
358| int bx, by;
359|
360| #if 0
361| pset( in->x1, in->y1, 0x00FF00 );
362| pset( in->x2, in->y2, 0x00FF00 );
363| pset( in->x3, in->y3, 0x00FF00 );
364| pset( in->x4, in->y4, 0x00FF00 );
365| #endif
366|
367| out1->x2 = (in->x1 + in->x2) / 2; /* a */
368| out1->y2 = (in->y1 + in->y2) / 2;
369| bx = (in->x2 + in->x3) / 2; /* b */
370| by = (in->y2 + in->y3) / 2;
371| out2->x3 = (in->x3 + in->x4) / 2; /* c */
372| out2->y3 = (in->y3 + in->y4) / 2;
373| out1->x3 = (out1->x2 + bx) / 2; /* d */
374| out1->y3 = (out1->y2 + by) / 2;
375| out2->x2 = (bx + out2->x3) / 2; /* e */
376| out2->y2 = (by + out2->y3) / 2;
377| *x = (out1->x3 + out2->x2) / 2; /* f */
378| *y = (out1->y3 + out2->y2) / 2;
379|
380| #if 0
381| pset( out1->x2, out1->y2, 0xFF0000 );
382| pset( bx, by, 0xFF0000 );
383| pset( out2->x3, out2->y3, 0xFF0000 );
384| pset( out1->x3, out1->y3, 0xFF0000 );
385| pset( out2->x2, out2->y2, 0xFF0000 );
386| #endif
387|
388| out1->x1 = in->x1; out1->y1 = in->y1;
389| out1->x4 = *x; out1->y4 = *y;
390| out2->x1 = *x; out2->y1 = *y;
391| out2->x4 = in->x4; out2->y4 = in->y4;
392|}
393|
394|void Draw_BezierCup_copy( Draw_BezierCup* a, Draw_BezierCup* b )
395|{
396| a->x1 = b->x1; a->y1 = b->y1;
397| a->x2 = b->x2; a->y2 = b->y2;
398| a->x3 = b->x3; a->y3 = b->y3;
399| a->x4 = b->x4; a->y4 = b->y4;
400|}
401|
402|
403|#endif /* USES_SSTACK */
404|
405|
406|/**************************************************************************
407|* 11. <<< 矩形塗りつぶし [Draw_rectFill()] >>>
408|***************************************************************************/
409|void Draw_rectFill( Draw* m, int x1, int y1, int x2, int y2,
410| int color )
411|{
412| int x,y;
413|
414| #ifdef _CHECKER
415| if ( x1 > x2 ) error();
416| if ( y1 > y2 ) error();
417| #endif
418|
419| for ( x = x1; x <= x2; x++ )
420| for ( y = y1; y <= y2; y++ )
421| Draw_pset( m, x, y, color );
422|}
423|
424|
425|#ifdef USES_THREED
426|#ifdef USES_SCALE
427|
428|/***********************************************************************
429|* 12. <<< 3次元で線分を描く [Draw_line3dP()] >>>
430|************************************************************************/
431|void Draw_line3dP( Draw* draw, ThreeD_ViewL* viewp, Scale* scale,
432| ThreeD_XYZ* p1, ThreeD_XYZ* p2, int color )
433|{
434| ThreeD_XYZ sp1, sp2;
435| int x1,y1,xx,yy;
436|
437| ThreeD_XYZ_get2D( p1, viewp, &sp1 );
438| ThreeD_XYZ_get2D( p2, viewp, &sp2 );
439|
440| x1 = (int)Scale_toGX( scale, sp1.x );
441| y1 = (int)Scale_toGY( scale, sp1.y );
442| xx = (int)Scale_toGX( scale, sp2.x );
443| yy = (int)Scale_toGY( scale, sp2.y );
444| Draw_line( draw, x1,y1, xx,yy, color );
445|}
446|
447|#endif /* USES_SCALE */
448|#endif /* USES_THREED */
449|
450|#ifdef USES_THREED
451|#ifdef USES_SCALE
452|
453|/***********************************************************************
454|* 13. <<< 3次元で線分を描く [Draw_line3d()] >>>
455|************************************************************************/
456|void Draw_line3d( Draw* draw, ThreeD_ViewL* viewp, Scale* scale,
457| double x1, double y1, double z1,
458| double x2, double y2, double z2, int color )
459|{
460| ThreeD_XYZ p1, p2;
461|
462| p1.x = x1; p1.y = y1; p1.z = z1;
463| p2.x = x2; p2.y = y2; p2.z = z2;
464|
465| Draw_line3dP( draw, viewp, scale, &p1, &p2, color );
466|}
467|
468|#endif /* USES_SCALE */
469|#endif /* USES_THREED */
470|
471|#ifdef USES_THREED2
472|#ifdef USES_SCALE3
473|
474|/***********************************************************************
475|* 14. <<< 3次元で線分を描く [Draw_line3dP2()] >>>
476|************************************************************************/
477|void Draw_line3dP2( Draw* draw, ThreeD2_ViewL* viewp, Scale3* scale,
478| ThreeD2_XYZ* p1, ThreeD2_XYZ* p2, int color )
479|{
480| ThreeD2_XYZ sp1, sp2;
481| int x1,y1,xx,yy;
482|
483| ThreeD2_XYZ_get2D( p1, viewp, &sp1 );
484| ThreeD2_XYZ_get2D( p2, viewp, &sp2 );
485|
486| x1 = Scale3_toGX( scale, sp1.x );
487| y1 = Scale3_toGY( scale, sp1.y );
488| xx = Scale3_toGX( scale, sp2.x );
489| yy = Scale3_toGY( scale, sp2.y );
490|
491| Draw_line( draw, x1,y1, xx,yy, color );
492|}
493|
494|#endif /* USES_SCALE3 */
495|#endif /* USES_THREED2 */
496|
497|#ifdef USES_THREED2
498|#ifdef USES_SCALE3
499|
500|/***********************************************************************
501|* 15. <<< 3次元で線分を描く [Draw_line3d2()] >>>
502|************************************************************************/
503|void Draw_line3d2( Draw* draw, ThreeD2_ViewL* viewp, Scale3* scale,
504| int x1, int y1, int z1,
505| int x2, int y2, int z2, int color )
506|{
507| ThreeD2_XYZ p1, p2;
508|
509| p1.x = x1; p1.y = y1; p1.z = z1;
510| p2.x = x2; p2.y = y2; p2.z = z2;
511|
512| Draw_line3dP2( draw, viewp, scale, &p1, &p2, color );
513|}
514|
515|#endif /* USES_SCALE3 */
516|#endif /* USES_THREED2 */
517|
518|#ifdef USES_ASCII
519|
520|/**************************************************************************
521|* 16. <<< ASCII 半角文字の表示 [Draw_ascii()] >>>
522|*【引数】
523|* ・char code; 文字 ASCII コード
524|*【補足】
525|*・半角文字は 8×16 pixel です。
526|***************************************************************************/
527|void Draw_ascii( Draw* m, int x, int y, char code, int color )
528|{
529| extern unsigned char asciidata[];
530| int iCode, iCodeOver;
531| #define fontWidth 8 /* 文字の横ピクセル数 */
532|
533|#if 0
534| /* クリッピング(1) */
535| if ( x <= Draw_getClipMinX(m) - fontWidth / 2 ||
536| x > Draw_getClipMaxX(m) ||
537| y <= Draw_getClipMinY(m) - fontWidth ||
538| y > Draw_getClipMaxY(m) )
539| return;
540|#endif
541|
542| /* 文字の一部でも表示画面よりはみ出たら表示しない */
543| if ( x < 0 || x + fontWidth -1 >= Draw_getWidth(m) ||
544| y < 0 || y + 15 >= Draw_getHeight(m) ) {
545| #ifdef Draw_ChkCharOut
546| #ifdef _CHECKER
547| #ifdef USES_WATCH
548| watch( 0, 0 ); watch( x, y ); watch_s( code, "ascii is out" );
549| brk( 1,1,0xFFFF, 0xFFFF, 1 );
550| #endif
551| #endif
552| #endif
553| return;
554| }
555|
556| /* 表示 */
557| iCode = (unsigned char)code * 16;
558| iCodeOver = iCode + 16;
559| for ( iCode; iCode < iCodeOver; iCode ++ ) {
560| #ifdef _CHECKER
561| if ( Screen_getPixelPerByte(m) != 2 ) error();
562| #endif
563|
564| Draw_psets( m, x, y, &asciidata[iCode], fontWidth, color );
565| y++;
566| }
567|
568| #undef fontWidth
569|}
570|#endif
571|
572|
573|#ifdef USES_JISDATA
574|
575|/**************************************************************************
576|* 17. <<< JIS 漢字の表示 [Draw_jis()] >>>
577|* ・code : 漢字 JIS コード
578|***************************************************************************/
579|void Draw_jis( Draw* m, int x, int y, unsigned short code, int color )
580|{
581| extern unsigned char jisdata[];
582| int iCode, iCodeOver;
583| #define fontWidth 16
584|
585| /* 文字の一部でも表示画面よりはみ出たら表示しない */
586| if ( x < 0 || x + fontWidth -1 >= Draw_getWidth(m) ||
587| y < 0 || y + 15 >= Draw_getHeight(m) ) {
588| #ifdef Draw_ChkCharOut
589| #ifdef _CHECKER
590| watch( 0, 0 ); watch( x, y ); watch_s( code, "jis is out" );
591| brk( 1,1,0xFFFF, 0xFFFF, 1 );
592| #endif
593| #endif
594| return;
595| }
596|
597| /* クリッピング(1) */
598|#if 0
599| if ( m->sc == &DScreen_sc_Draw_Scr ) {
600| if ( x <= DScreen_getClipMinX(m) - fontWidth ||
601| x > DScreen_getClipMaxX(m) ||
602| y <= DScreen_getClipMinY(m) - fontWidth ||
603| y > DScreen_getClipMaxY(m) ) {
604| return;
605| }
606| }
607|#endif
608|
609| /* 表示 */
610| iCode = (code - 0x2120) * 32;
611| iCodeOver = iCode + 32;
612| for ( iCode; iCode < iCodeOver; iCode += 2 ) {
613| Draw_psets( m, x, y, &jisdata[iCode], fontWidth, color );
614| y++;
615| }
616|
617| #undef fontWidth
618|}
619|#endif
620|
621|
622|#ifdef USES_MASK
623|/**************************************************************************
624|* 18. <<< 16×16のピクセル・パターンを描画する [Draw_pattern()] >>>
625|*【引数】
626|* ・pattern : ピクセル・パターンが格納されているアドレス
627|*【補足】
628|*・ピクセル・パターンは 1bpp で 32byte 分、用意してください。
629|*・たとえば、シンボルの表示に使います。
630|***************************************************************************/
631|void Draw_pattern( Draw* m, int x, int y, char* pattern,
632| int color )
633|{
634| char* pattern_over = pattern + 32;
635| #define fontWidth 16
636|
637|#if 0
638| /* クリッピング(1) */
639| if ( x <= Draw_getClipMinX(m) - fontWidth ||
640| x > Draw_getClipMaxX(m) ||
641| y <= Draw_getClipMinY(m) - fontWidth ||
642| y > Draw_getClipMaxY(m) )
643| return;
644|#endif
645|
646| /* 16×16のピクセル・パターンを描画する */
647| for ( pattern ; pattern < pattern_over; pattern += 2 ) {
648| Draw_psets( m, x, y, (unsigned char*)pattern, fontWidth, color );
649| y++;
650| }
651|
652| #undef fontWidth
653|}
654|#endif /* USES_MASK */
655|
656|
657|/**************************************************************************
658|* 19. <<< ペン(太い)[Draw_Pen...] >>>
659|***************************************************************************/
660|#ifdef USES_SCREEN
661|int* Draw_Pen_maru[9];
662|/* penDataは [0] が x と y の数, [奇数]が x, [偶数]が y */
663|static int penData_maru0[1] = { 0 };
664|static int penData_maru1[3] = { 2, 0,0 };
665|static int penData_maru2[9] = { 8, 0,0, 1,1, 0,1, 1,0 };
666|static int penData_maru3[11]= { 10, 0,0, 1,0, -1,0, 0,1, 0,-1 };
667|static int penData_maru4[25] =
668| { 24, 0,0, 1,1, 0,1, 1,0,
669| 0,-1, 1,-1, -1,0, 2,0, -1,1, 2,1, 0,2, 1,2 };
670|static int penData_maru5[27] =
671| { 26, 0,0, -1,0, 1,0, 0,-1, 0,1, -1,-1, 1,1, 1,-1, -1,1,
672| -2,0, 2,0, 0,-2, 0,2 };
673|/*
674|* # +# # ## #
675|* ## #+# #+## ###
676|* # #### ##+##
677|* ## ###
678|* #
679|*/
680|
681|static int penData_maru6[49] =
682| { 48, 0,0, 1,1, 1,0, 0,1, -1,-1, -1,0, -1,1, -1,2,
683| 0,-1, 0,2, 1,-1, 1,2, 2,-1, 2,0, 2,1, 2,2,
684| -2,0, -2,1, 0,-2, 0,3, 1,-2, 1,3, 3,0, 3,1 };
685|/*
686|* ##
687|* ####
688|* ##+###
689|* ######
690|* ####
691|* ##
692|*/
693|
694|static int penData_maru7[75] =
695| { 74, 0,0, 1,1, 1,0, 0,1, -1,-1, -1,0, -1,1, -1,2,
696| 0,-1, 0,2, 1,-1, 1,2, 2,-1, 2,0, 2,1, 2,2,
697| -2,0, -2,1, 0,-2, 0,3, 1,-2, 1,3, 3,0, 3,1,
698| -1,-3, 0,-3, 1,-3, -2,-2, -1,-2, 2,-2,
699| -3,-1, -2,-1, 3,-1, -3,0, -3,1, -2,2, -1,3 };
700|/*
701|* ***
702|* **##*
703|* **####*
704|* *##+###
705|* *######
706|* *#### *... 6 からの差分
707|* *##
708|*/
709|
710|static int penData_maru8[81] =
711| { 80, 0,0, 1,1, 1,0, 0,1, -1,-1, -1,0, -1,1, -1,2,
712| 0,-1, 0,2, 1,-1, 1,2, 2,-1, 2,0, 2,1, 2,2,
713| -2,0, -2,1, 0,-2, 0,3, 1,-2, 1,3, 3,0, 3,1,
714| 0,-3, 1,-3, -1,-2, 2,-2, -2,-1, 3,-1, -3,0, 4,0,
715| -3,1, 4,1, -2,2, 3,2, -1,3, 2,3, 0,4, 1,4 };
716|/*
717|* **
718|* *##*
719|* *####*
720|* *##+###*
721|* *######*
722|* *####* *... 6 からの差分
723|* *##*
724|* **
725|*/
726|
727|/*
728|* 初期化
729|*/
730|void Draw_Pen_init()
731|{
732| Draw_Pen_maru[0] = penData_maru0;
733| Draw_Pen_maru[1] = penData_maru1;
734| Draw_Pen_maru[2] = penData_maru2;
735| Draw_Pen_maru[3] = penData_maru3;
736| Draw_Pen_maru[4] = penData_maru4;
737| Draw_Pen_maru[5] = penData_maru5;
738| Draw_Pen_maru[6] = penData_maru6;
739| Draw_Pen_maru[7] = penData_maru7;
740| Draw_Pen_maru[8] = penData_maru8;
741|}
742|#endif /* USES_SCREEN */
743|
744|
745|#ifdef USES_SCREEN
746|#ifdef USES_MASK
747|/**************************************************************************
748|* 20. <<< Screen work 画面から Screen Active 画面へコピー [Draw_Scr_flushFromScreen()] >>>
749|* 詳細は Screen_flushTo() を参照
750|***************************************************************************/
751|#undef Draw_Scr_flushFromScreen
752|void Draw_Scr_flushFromScreen( Screen* work, Mask_A* mask,
753| int baseX, int baseY, int clipX )
754|{
755| #ifdef _CHECHER
756| error();
757| #endif
758|}
759|
760|#endif
761|#endif
762|
763|#ifdef USES_DSCREEN
764|
765|/**************************************************************************
766|* 21. <<< DScreen work 画面から Screen Active 画面へコピー [Draw_Scr_flushFromDScreen()] >>>
767|* 引数の内容は DScreen_flushTo() を参照
768|***************************************************************************/
769|#undef Draw_Scr_flushFromDScreen
770|void Draw_Scr_flushFromDScreen( DScreen* work, Mask_A* mask,
771| int baseX, int baseY, int clipX )
772|{
773| #ifdef _CHECHER
774| error();
775| #endif
776|}
777|
778|#endif
779|
780|/*************************************************************************
781|* 22. <<< ベクトル成分 dx,dy から方向番号を取得する [Draw_getDirec()] >>>
782|*
783|*
784|*
785|*【引数】
786|* ・int dx,dy; 方向ベクトルの x,y 成分
787|* ・int 返り値; 方向番号
788|*【補足】
789|*・返り値は、全方向を8分割して、左上水平寄りの 0度〜 45度を0とします。
790|* 以後、右回りに1〜7とします。(数学の一般角とは逆方向)
791|*・この値は、|dx|(絶対値)と|dy| のうち、大きい方が dx なら、第1ビットが0、
792|* dy なら第1ビットが1になります。
793|*・|dx|>|dy| の場合、dx がプラスなら第2ビットが0、マイナスなら1になり、
794|* dy がプラスなら第0ビットから第2ビットまでのうち値が1になっている数が
795|* 奇数になります。
796|*・|dx|<|dy| の場合、dy がプラスなら第2ビットが0、マイナスなら1になり、
797|* dx がプラスなら第0ビットから第2ビットまでのうち値が1になっている数が
798|* 奇数になります。
799|**************************************************************************/
800|int Draw_getDirec( int dx, int dy )
801|{
802| if ( dx > 0 ) {
803| if ( dy < 0 ) {
804| if ( dx > -dy ) return 0;
805| else return 7;
806| }
807| else {
808| if ( dx > dy ) return 1;
809| else return 2;
810| }
811| }
812| else {
813| if ( dy < 0 ) {
814| if ( dx < dy ) return 5;
815| else return 6;
816| }
817| else {
818| if ( -dx > dy ) return 4;
819| else return 3;
820| }
821| }
822|}
823|
824|